diff options
author | Prasanth Ullattil <prasanth.ullattil@nokia.com> | 2012-03-20 08:55:53 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-04-03 13:35:22 +0200 |
commit | 12096d31c836ad606462750de96a66ac69cbd5c7 (patch) | |
tree | 0107ddab9c6dc7b90df37fe0eb65f00cc1727dbd | |
parent | 1359220a1fc067725ce0fe904421509247c97fd7 (diff) |
Moving QML plugin to the new JsonDb client API
1) All QML elemnts use the new client C++ API
2) Changes since is not supported
3) QML auto tests link against the new API
Done-with: Liang Qi <liang.qi@nokia.com>
Done-with: Tapani Mikola <tapani.mikola@nokia.com>
Change-Id: Ifbbeb4cce855ebd275389f3f69ee9b3be6092d64
Reviewed-by: Tapani Mikola <tapani.mikola@nokia.com>
Reviewed-by: Prasanth Ullattil <prasanth.ullattil@nokia.com>
Reviewed-by: Denis Dzyubenko <denis.dzyubenko@nokia.com>
47 files changed, 2850 insertions, 1731 deletions
diff --git a/examples/declarative/cachingmodel/cachingmodel.qml b/examples/declarative/cachingmodel/cachingmodel.qml index 375edf4b..15b6c6d5 100644 --- a/examples/declarative/cachingmodel/cachingmodel.qml +++ b/examples/declarative/cachingmodel/cachingmodel.qml @@ -60,22 +60,35 @@ Item { sortOrder:"[/firstName]" cacheSize:150 } + + function indexCreateCallback(error, response) { + console.log("Index Create callback #############"); + if (error) { + console.log("Failed to create Index "+JSON.stringify(error)); + return; + } + console.log("Index created"); + } + function createIndex() { + console.log("createIndex ***************"); var indexDefinition = { "_type": "Index", "name": "firstName", "propertyName": "firstName", "propertyType": "string" }; - nokiaPartition.create(indexDefinition); - nokiaPartition2.create(indexDefinition); + nokiaPartition.create(indexDefinition, indexCreateCallback); + nokiaPartition2.create(indexDefinition, indexCreateCallback); + console.log("createIndex ***************"); } function partitionCreateCallback(error, response) { if (error) { - console.log("Failed to create Partitions"); + console.log("Failed to create Partitions :"+JSON.stringify(error)); return; } + console.log("Partition Create callback #############"); nokiaPartition = JsonDb.partition("com.nokia.shared", topLevelItem); nokiaPartition2 = JsonDb.partition("com.nokia.shared2", topLevelItem); createIndex(); @@ -83,6 +96,7 @@ Item { } function checkForPartitions(error, result) { + console.log("checkForPartitions"); if (error) { console.log("Failed to list Partitions"); } else { @@ -114,9 +128,29 @@ Item { } } } + // Logs notifications of type "MyContacts" in partition "com.nokia.shared" + JsonDb.Partition { + name: "com.nokia.shared" + JsonDb.Notification { + query: '[?_type="MyContacts"]' + onNotification: { + switch (action) { + case JsonDb.Notification.Create : + console.log("{_uuid :" + result._uuid + "} created"); + break; + case JsonDb.Notification.Update : + console.log("{_uuid :" + result._uuid + "} was updated"); + break; + case JsonDb.Notification.Remove : + console.log("{_uuid :" + result._uuid + "} was removed"); + break; + } + } + } + } Component.onCompleted: { - JsonDb.listPartitions(checkForPartitions, topLevelItem); + JsonDb.listPartitions(checkForPartitions); } Button { diff --git a/src/imports/jsondb/jsondatabase.cpp b/src/imports/jsondb/jsondatabase.cpp index 491fe85d..951c5ef5 100644 --- a/src/imports/jsondb/jsondatabase.cpp +++ b/src/imports/jsondb/jsondatabase.cpp @@ -41,22 +41,14 @@ #include "jsondatabase.h" #include "jsondbpartition.h" -#include "jsondb-object.h" #include <QJSEngine> #include <QQmlEngine> +#include <qjsondbobject.h> #include <qdebug.h> QT_BEGIN_NAMESPACE_JSONDB -struct Uuid -{ - uint data1; - ushort data2; - ushort data3; - uchar data4[8]; -}; - -static const Uuid JsonDbNamespace = {0x6ba7b810, 0x9dad, 0x11d1, { 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} }; +QPointer<QJsonDbConnection> JsonDatabase::connection(0); /*! \qmlclass JsonDatabase @@ -70,17 +62,13 @@ static const Uuid JsonDbNamespace = {0x6ba7b810, 0x9dad, 0x11d1, { 0x80, 0xb4, 0 JsonDatabase::JsonDatabase(QObject *parent) :QObject(parent) { - connect(&jsonDb, SIGNAL(response(int,const QVariant&)), - this, SLOT(dbResponse(int,const QVariant&)), - Qt::QueuedConnection); - connect(&jsonDb, SIGNAL(error(int,int,QString)), - this, SLOT(dbErrorResponse(int,int,QString)), - Qt::QueuedConnection); - } JsonDatabase::~JsonDatabase() { + if (connection) { + delete connection; + } } /*! @@ -133,9 +121,16 @@ void JsonDatabase::listPartitions(const QJSValue &listCallback) qWarning() << "Invalid callback specified."; return; } - QString query(QLatin1String("[?_type=\"Partition\"]")); - int id = jsonDb.query(query, 0, -1); - listCallbacks.insert(id, listCallback); + QJsonDbReadRequest *request = new QJsonDbReadRequest; + request->setQuery(QLatin1String("[?_type=\"Partition\"]")); + connect(request, SIGNAL(finished()), this, SLOT(onQueryFinished())); + connect(request, SIGNAL(finished()), request, SLOT(deleteLater())); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SLOT(onQueryError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + request, SLOT(deleteLater())); + sharedConnection().send(request); + listCallbacks.insert(request, listCallback); } /*! @@ -156,29 +151,23 @@ void JsonDatabase::listPartitions(const QJSValue &listCallback) QString JsonDatabase::uuidFromString(const QString &identifier) { - const QUuid ns(JsonDbNamespace.data1, JsonDbNamespace.data2, JsonDbNamespace.data3, - JsonDbNamespace.data4[0], JsonDbNamespace.data4[1], JsonDbNamespace.data4[2], - JsonDbNamespace.data4[3], JsonDbNamespace.data4[4], JsonDbNamespace.data4[5], - JsonDbNamespace.data4[6], JsonDbNamespace.data4[7]); - return QUuid::createUuidV3(ns, identifier).toString(); + return QJsonDbObject::createUuidFromString(identifier).toString(); } -void JsonDatabase::dbResponse(int id, const QVariant &result) +void JsonDatabase::onQueryFinished() { - if (listCallbacks.contains(id)) { - // Make sure that id exists in the map. - QJSValue callback = listCallbacks[id]; + QJsonDbReadRequest *request = qobject_cast<QJsonDbReadRequest *>(sender()); + if (listCallbacks.contains(request)) { + QJSValue callback = listCallbacks[request]; QJSEngine *engine = callback.engine(); QJSValueList args; args << QJSValue(QJSValue::UndefinedValue); - QVariantMap objectMap = result.toMap(); - if (objectMap.contains(QLatin1String("data"))) { - QVariantList items = objectMap.value(QLatin1String("data")).toList(); - int count = items.count(); + QList<QJsonObject> objects = request->takeResults(); + int count = objects.count(); + if (count) { QJSValue response = engine->newArray(count); for (int i = 0; i < count; ++i) { - QVariantMap object = items.at(i).toMap(); - QString partitionName = object.value(QLatin1String("name")).toString(); + QString partitionName = objects[i].value(QLatin1String("name")).toString(); response.setProperty(i, engine->newQObject(partition(partitionName))); } args << response; @@ -186,14 +175,15 @@ void JsonDatabase::dbResponse(int id, const QVariant &result) args << engine->newArray(); } callback.call(args); - listCallbacks.remove(id); + listCallbacks.remove(request); } } -void JsonDatabase::dbErrorResponse(int id, int code, const QString &message) +void JsonDatabase::onQueryError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message) { - if (listCallbacks.contains(id)) { - QJSValue callback = listCallbacks[id]; + QJsonDbReadRequest *request = qobject_cast<QJsonDbReadRequest *>(sender()); + if (listCallbacks.contains(request)) { + QJSValue callback = listCallbacks[request]; QJSEngine *engine = callback.engine(); QJSValueList args; @@ -204,9 +194,19 @@ void JsonDatabase::dbErrorResponse(int id, int code, const QString &message) args << engine->toScriptValue(QVariant(error))<< engine->newArray(); callback.call(args); - listCallbacks.remove(id); + listCallbacks.remove(request); } } +QJsonDbConnection& JsonDatabase::sharedConnection() +{ + if (!connection) { + connection = new QJsonDbConnection(); + connection->connectToServer(); + } + return *connection; +} + + #include "moc_jsondatabase.cpp" QT_END_NAMESPACE_JSONDB diff --git a/src/imports/jsondb/jsondatabase.h b/src/imports/jsondb/jsondatabase.h index a1803a81..19ae5a43 100644 --- a/src/imports/jsondb/jsondatabase.h +++ b/src/imports/jsondb/jsondatabase.h @@ -45,7 +45,9 @@ #include <QObject> #include <QJSValue> #include <QPointer> -#include "jsondb-client.h" +#include <QMap> +#include <QJsonDbConnection> +#include <QJsonDbReadRequest> QT_BEGIN_NAMESPACE_JSONDB @@ -61,14 +63,15 @@ public: Q_INVOKABLE JsonDbPartition* partition(const QString &partitionName); Q_INVOKABLE void listPartitions(const QJSValue &callback); Q_INVOKABLE QString uuidFromString(const QString &identifier); + static QJsonDbConnection& sharedConnection(); private Q_SLOTS: - void dbResponse(int id, const QVariant &result); - void dbErrorResponse(int id, int code, const QString &message); + void onQueryFinished(); + void onQueryError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message); private: - QMap<int, QJSValue> listCallbacks; - JsonDbClient jsonDb; + QMap<QJsonDbReadRequest*, QJSValue> listCallbacks; + static QPointer<QJsonDbConnection> connection; }; QT_END_NAMESPACE_JSONDB diff --git a/src/imports/jsondb/jsondb.pro b/src/imports/jsondb/jsondb.pro index 71d33898..9ffbc3e7 100644 --- a/src/imports/jsondb/jsondb.pro +++ b/src/imports/jsondb/jsondb.pro @@ -3,9 +3,9 @@ TARGETPATH = QtJsonDb include(../qimportbase.pri) -QT += network qml jsondbcompat-private +QT += network qml jsondb jsondb-private -DESTDIR = $$QT.jsondbcompat.imports/$$TARGETPATH +DESTDIR = $$QT.jsondb.imports/$$TARGETPATH target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH qmldir.files += $$PWD/qmldir @@ -33,30 +33,30 @@ include(../../common/common.pri) HEADERS += \ jsondbpartition.h \ jsondbnotification.h \ - jsondbsortinglistmodel.h \ - jsondbsortinglistmodel_p.h \ - jsondblistmodel.h \ - jsondblistmodel_p.h \ plugin.h \ jsondatabase.h \ jsondbqueryobject.h \ jsondbchangessinceobject.h \ + jsondbmodelutils.h \ jsondbmodelcache.h \ + jsondblistmodel.h \ + jsondblistmodel_p.h \ + jsondbsortinglistmodel_p.h \ + jsondbsortinglistmodel.h \ jsondbcachinglistmodel_p.h \ - jsondbcachinglistmodel.h \ - jsondbmodelutils.h + jsondbcachinglistmodel.h SOURCES += \ jsondbpartition.cpp \ jsondbnotification.cpp \ - jsondbsortinglistmodel.cpp \ - jsondblistmodel.cpp \ plugin.cpp \ jsondatabase.cpp \ jsondbqueryobject.cpp \ jsondbchangessinceobject.cpp \ - jsondbcachinglistmodel.cpp \ + jsondbmodelutils.cpp \ jsondbmodelcache.cpp \ - jsondbmodelutils.cpp + jsondblistmodel.cpp \ + jsondbsortinglistmodel.cpp \ + jsondbcachinglistmodel.cpp OTHER_FILES += jsondb.json diff --git a/src/imports/jsondb/jsondbcachinglistmodel.cpp b/src/imports/jsondb/jsondbcachinglistmodel.cpp index 7306d5db..d62c383f 100644 --- a/src/imports/jsondb/jsondbcachinglistmodel.cpp +++ b/src/imports/jsondb/jsondbcachinglistmodel.cpp @@ -43,7 +43,6 @@ #include "jsondbcachinglistmodel.h" #include "jsondbcachinglistmodel_p.h" -#include "private/jsondb-strings_p.h" #include "plugin.h" #include <QJSEngine> @@ -70,13 +69,6 @@ JsonDbCachingListModelPrivate::JsonDbCachingListModelPrivate(JsonDbCachingListMo void JsonDbCachingListModelPrivate::init() { - Q_Q(JsonDbCachingListModel); - q->connect(&dbClient, SIGNAL(response(int,const QVariant&)), - q, SLOT(_q_jsonDbResponse(int,const QVariant&)), - Qt::QueuedConnection); - q->connect(&dbClient, SIGNAL(error(int,int,const QString&)), - q, SLOT(_q_jsonDbErrorResponse(int,int,const QString&)), - Qt::QueuedConnection); } void JsonDbCachingListModelPrivate::setCacheParams(int maxItems) @@ -84,13 +76,24 @@ void JsonDbCachingListModelPrivate::setCacheParams(int maxItems) objectCache.setPageSize(maxItems); chunkSize = objectCache.chunkSize(); lowWaterMark = objectCache.chunkSize()/4; - //lowWaterMark = objectCache.pageSize/4; } JsonDbCachingListModelPrivate::~JsonDbCachingListModelPrivate() { - // Why do we need to do this while destroying the object clearNotifications(); + while (!keyRequests.isEmpty()) { + delete keyRequests[0]; + keyRequests.removeFirst(); + } + while (!indexRequests.isEmpty()) { + delete indexRequests[0]; + indexRequests.removeFirst(); + } + while (!valueRequests.isEmpty()) { + delete valueRequests[0]; + valueRequests.removeFirst(); + } + } // insert item notification handler @@ -276,18 +279,20 @@ void JsonDbCachingListModelPrivate::createObjectRequests(int startIndex, int max r.lastOffset = indexNSizes[i].index; r.lastSize = -1; r.requestCount = indexNSizes[i].count; - r.requestId = dbClient.query(query+sortOrder, indexNSizes[i].index, - qMin(r.requestCount, chunkSize), - partitionObjects[i]->name()); + QJsonDbReadRequest *request = valueRequests[i]->newRequest(i); + request->setQuery(query+sortOrder); + request->setProperty("queryOffset", indexNSizes[i].index); + request->setQueryLimit(qMin(r.requestCount, chunkSize)); + request->setPartition(partitionObjects[i]->name()); + JsonDatabase::sharedConnection().send(request); #ifdef JSONDB_LISTMODEL_DEBUG qDebug()<<"Query"<<query+sortOrder<<partitionObjects[i]->name(); - qDebug()<<"Request "<<r.requestId << + qDebug()<<"Request "<<request->property("requestId") << "Total Count "<<r.requestCount << "Offset"<<r.lastOffset<< "Count "<<qMin(r.requestCount,chunkSize); #endif } else { - r.requestId = -1; r.lastSize = 0; r.requestCount = 0; } @@ -295,13 +300,9 @@ void JsonDbCachingListModelPrivate::createObjectRequests(int startIndex, int max delete [] indexNSizes; } -void JsonDbCachingListModelPrivate::verifyIndexSpec(const QVariant &v, int partitionIndex) +void JsonDbCachingListModelPrivate::verifyIndexSpec(const QVariantList &items, int partitionIndex) { Q_Q(JsonDbCachingListModel); - QVariantMap m = v.toMap(); - QVariantList items; - if (m.contains(QLatin1String("data"))) - items = m.value(QLatin1String("data")).toList(); SortIndexSpec &indexSpec = partitionIndexDetails[partitionIndex].spec; QString propertyFunction; QString indexName; @@ -354,24 +355,17 @@ void JsonDbCachingListModelPrivate::verifyIndexSpec(const QVariant &v, int parti } } -void JsonDbCachingListModelPrivate::fillKeys(const QVariant &v, int partitionIndex) +void JsonDbCachingListModelPrivate::fillKeys(const QVariantList &items, int partitionIndex, const QString &sortKey) { Q_Q(JsonDbCachingListModel); - QVariantMap m = v.toMap(); - QVariantList items; - if (m.contains(QLatin1String("data"))) - items = m.value(QLatin1String("data")).toList(); // Check if the sort key is same as requested. // We can only support this model if an index is present - if (m.contains(QLatin1String("sortKeys"))) { - const QVariantList &sortKeys = m.value(QLatin1String("sortKeys")).toList(); - if (!(sortKeys.count() && sortKeys[0].toString() == orderProperties[0])) { - qWarning() << "Error JsonDbCachingListModel requires Index for "<<orderProperties[0]<<" Sort Keys"<<sortKeys; - reset(); - state = JsonDbCachingListModel::Error; - emit q->stateChanged(state); - return; - } + if (sortKey != orderProperties[0]) { + qWarning() << "Error JsonDbCachingListModel requires Index for "<<orderProperties[0]<<" Sort Keys"<<sortKey; + reset(); + state = JsonDbCachingListModel::Error; + emit q->stateChanged(state); + return; } RequestInfo &r = partitionKeyRequestDetails[partitionIndex]; r.lastSize = items.size(); @@ -400,7 +394,7 @@ void JsonDbCachingListModelPrivate::fillKeys(const QVariant &v, int partitionInd #endif if (!objectUuids.count()) { for (int i = 0; i<partitionObjectDetails.count(); i++) { - fillData(QVariant(), i); + fillData(QVariantList(), i); } return; } @@ -419,13 +413,9 @@ void JsonDbCachingListModelPrivate::emitDataChanged(int from, int to) emit q->dataChanged(modelIndexFrom, modelIndexTo); } -void JsonDbCachingListModelPrivate::fillData(const QVariant &v, int partitionIndex) +void JsonDbCachingListModelPrivate::fillData(const QVariantList &items, int partitionIndex) { Q_Q(JsonDbCachingListModel); - QVariantMap m = v.toMap(); - QVariantList items; - if (m.contains(QLatin1String("data"))) - items = m.value(QLatin1String("data")).toList(); RequestInfo &r = partitionObjectDetails[partitionIndex]; r.lastSize = items.size(); r.requestCount -= r.lastSize; @@ -500,7 +490,7 @@ void JsonDbCachingListModelPrivate::fillData(const QVariant &v, int partitionInd emit q->stateChanged(state); for (int i = 0; i < pendingNotifications.size(); i++) { const NotifyItem &pending = pendingNotifications[i]; - sendNotifications(pending.notifyUuid, pendingNotifications[i].item, pendingNotifications[i].action); + sendNotifications(pending.partitionIndex, pending.item, pending.action); } pendingNotifications.clear(); if (requestQueue.count()) { @@ -573,10 +563,12 @@ void JsonDbCachingListModelPrivate::fetchIndexSpec(int index) state = JsonDbCachingListModel::Querying; emit q->stateChanged(state); } - IndexInfo &r = partitionIndexDetails[index]; QPointer<JsonDbPartition> p = partitionObjects[index]; if (p) { - r.requestId = dbClient.query(queryForIndexSpec, 0, -1, p->name()); + QJsonDbReadRequest *request = indexRequests[index]->newRequest(index); + request->setQuery(queryForIndexSpec); + request->setPartition(p->name()); + JsonDatabase::sharedConnection().send(request); } } @@ -595,7 +587,11 @@ void JsonDbCachingListModelPrivate::fetchPartitionKeys(int index) if (p) { r.lastSize = -1; r.lastOffset = 0; - r.requestId = dbClient.query(queryForSortKeys, 0, chunkSize*2, p->name()); + QJsonDbReadRequest *request = keyRequests[index]->newRequest(index); + request->setQuery(queryForSortKeys); + request->setQueryLimit(chunkSize*2); + request->setPartition(p->name()); + JsonDatabase::sharedConnection().send(request); } } @@ -609,6 +605,9 @@ void JsonDbCachingListModelPrivate::initializeModel(bool reset) for (int i = 0; i < partitionObjectUuids.count(); i++) { partitionObjectUuids[i].clear(); } + for (int i = 0; i < partitionIndexDetails.count(); i++) { + partitionIndexDetails[i].clear(); + } } for (int i = 0; i < partitionObjects.count(); i++) { fetchIndexSpec(i); @@ -625,16 +624,25 @@ void JsonDbCachingListModelPrivate::fetchNextKeyChunk(int partitionIndex) { RequestInfo &r = partitionKeyRequestDetails[partitionIndex]; r.lastOffset += chunkSize*2; - r.requestId = dbClient.query(queryForSortKeys, r.lastOffset, - chunkSize*2, partitionObjects[partitionIndex]->name()); + QJsonDbReadRequest *request = keyRequests[partitionIndex]->newRequest(partitionIndex); + request->setQuery(queryForSortKeys); + request->setProperty("queryOffset", r.lastOffset); + request->setQueryLimit(chunkSize*2); + request->setPartition(partitionObjects[partitionIndex]->name()); + JsonDatabase::sharedConnection().send(request); + } void JsonDbCachingListModelPrivate::fetchNextChunk(int partitionIndex) { RequestInfo &r = partitionObjectDetails[partitionIndex]; - r.requestId = dbClient.query(query+sortOrder, r.lastOffset, - qMin(r.requestCount, chunkSize), - partitionObjects[partitionIndex]->name()); + QJsonDbReadRequest *request = valueRequests[partitionIndex]->newRequest(partitionIndex); + request->setQuery(query+sortOrder); + request->setProperty("queryOffset", r.lastOffset); + request->setQueryLimit(qMin(r.requestCount, chunkSize)); + request->setPartition(partitionObjects[partitionIndex]->name()); + JsonDatabase::sharedConnection().send(request); + } void JsonDbCachingListModelPrivate::prefetchNearbyPages(int index) @@ -687,15 +695,14 @@ void JsonDbCachingListModelPrivate::requestPageContaining(int index) } - void JsonDbCachingListModelPrivate::clearNotification(int index) { if (index >= partitionObjects.count()) return; RequestInfo &r = partitionObjectDetails[index]; - if (!r.notifyUuid.isEmpty()) { - dbClient.unregisterNotification(r.notifyUuid); + if (r.watcher) { + JsonDatabase::sharedConnection().removeWatcher(r.watcher); } r.clear(); } @@ -712,13 +719,16 @@ void JsonDbCachingListModelPrivate::createOrUpdateNotification(int index) if (index >= partitionObjects.count()) return; clearNotification(index); - JsonDbClient::NotifyTypes notifyActions = JsonDbClient::NotifyCreate - | JsonDbClient::NotifyUpdate| JsonDbClient::NotifyRemove; - partitionObjectDetails[index].notifyUuid= dbClient.registerNotification( - notifyActions , query, partitionObjects[index]->name(), - q, SLOT(_q_dbNotified(QString,QtAddOn::JsonDb::JsonDbNotification)), - q, SLOT(_q_dbNotifyReadyResponse(int,QVariant)), - SLOT(_q_dbNotifyErrorResponse(int,int,QString))); + QJsonDbWatcher *watcher = new QJsonDbWatcher(); + watcher->setQuery(query); + watcher->setWatchedActions(QJsonDbWatcher::Created | QJsonDbWatcher::Updated |QJsonDbWatcher::Removed); + watcher->setPartition(partitionObjects[index]->name()); + QObject::connect(watcher, SIGNAL(notificationsAvailable(int)), + q, SLOT(_q_notificationsAvailable())); + QObject::connect(watcher, SIGNAL(error(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)), + q, SLOT(_q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString))); + JsonDatabase::sharedConnection().addWatcher(watcher); + partitionObjectDetails[index].watcher = watcher; } void JsonDbCachingListModelPrivate::createOrUpdateNotifications() @@ -742,7 +752,8 @@ void JsonDbCachingListModelPrivate::parseSortOrder() ascendingOrder = true; ascendingOrders << ascendingOrder; orderProperties << orderMatch.cap(2); - orderPaths << orderMatch.cap(2).split('.'); + // We dont retrieve subobjects when retrieving sortkeys, only the actual value is retrieved + orderPaths << QStringList(orderMatch.cap(2)); if (firstMatch == -1) firstMatch = matchIndex; matchIndex += orderMatch.matchedLength(); @@ -758,42 +769,19 @@ void JsonDbCachingListModelPrivate::parseSortOrder() void JsonDbCachingListModelPrivate::setQueryForSortKeys() { // Query to retrieve the sortKeys - queryForSortKeys = (QString("%1%2") - .arg(query) - .arg(sortOrder)); -} - -int JsonDbCachingListModelPrivate::indexOfKeyIndexSpecId(int requestId) -{ - for (int i = 0; i < partitionIndexDetails.count(); i++) { - if (requestId == partitionIndexDetails[i].requestId) - return i; - } - return -1; -} - -int JsonDbCachingListModelPrivate::indexOfKeyRequestId(int requestId) -{ - for (int i = 0; i < partitionKeyRequestDetails.count(); i++) { - if (requestId == partitionKeyRequestDetails[i].requestId) - return i; - } - return -1; -} - -int JsonDbCachingListModelPrivate::indexOfRequestId(int requestId) -{ - for (int i = 0; i < partitionObjectDetails.count(); i++) { - if (requestId == partitionObjectDetails[i].requestId) - return i; + // TODO remove the "[= {}]" from query + queryForSortKeys = query + QLatin1String("[= { _uuid: _uuid"); + for (int i = 0; i < orderProperties.count() ; i++) { + queryForSortKeys += QLatin1String(", ") + orderProperties[i]+QLatin1String(" : ") + orderProperties[i]; } - return -1; + queryForSortKeys += QLatin1String("}]"); + queryForSortKeys += sortOrder; } -int JsonDbCachingListModelPrivate::indexOfNotifyUUID(const QString& notifyUuid) +int JsonDbCachingListModelPrivate::indexOfWatcher(QJsonDbWatcher *watcher) { for (int i = 0; i < partitionObjectDetails.count(); i++) { - if (notifyUuid == partitionObjectDetails[i].notifyUuid) + if (watcher == partitionObjectDetails[i].watcher) return i; } return -1; @@ -904,39 +892,33 @@ int JsonDbCachingListModelPrivate::indexOf(const QString &uuid) const return iterator_position(begin, end, i); } -void JsonDbCachingListModelPrivate::sendNotifications(const QString& currentNotifyUuid, const QVariant &v, JsonDbClient::NotifyType action) +void JsonDbCachingListModelPrivate::sendNotifications(int partitionIndex, const QVariantMap &v, QJsonDbWatcher::Action action) { - int idx = indexOfNotifyUUID(currentNotifyUuid); - if (idx == -1) - return; - - const QVariantMap &item = v.toMap(); - if (action == JsonDbClient::NotifyCreate) { - addItem(item, idx); - } else if (action == JsonDbClient::NotifyRemove) { - deleteItem(item, idx); - } else if (action == JsonDbClient::NotifyUpdate) { - updateItem(item, idx); + if (action == QJsonDbWatcher::Created) { + addItem(v, partitionIndex); + } else if (action == QJsonDbWatcher::Removed) { + deleteItem(v, partitionIndex); + } else if (action == QJsonDbWatcher::Updated) { + updateItem(v, partitionIndex); } } -void JsonDbCachingListModelPrivate::_q_jsonDbResponse(int id, const QVariant &v) +void JsonDbCachingListModelPrivate::_q_keyResponse(int index, const QList<QJsonObject> &v, const QString &sortKey) { - int idx = -1; - if ((idx = indexOfKeyRequestId(id)) != -1) { - partitionKeyRequestDetails[idx].requestId = -1; - partitionObjectDetails[idx].requestId = -1; - fillKeys(v, idx); - } else if ((idx = indexOfRequestId(id)) != -1) { - partitionObjectDetails[idx].requestId = -1; - fillData(v, idx); - } else if ((idx = indexOfKeyIndexSpecId(id)) != -1) { - partitionIndexDetails[idx].requestId = -1; - verifyIndexSpec(v, idx); - } + fillKeys(qjsonobject_list_to_qvariantlist(v), index, sortKey); +} + +void JsonDbCachingListModelPrivate::_q_valueResponse(int index, const QList<QJsonObject> &v) +{ + fillData(qjsonobject_list_to_qvariantlist(v), index); +} + +void JsonDbCachingListModelPrivate::_q_indexResponse(int index, const QList<QJsonObject> &v) +{ + verifyIndexSpec(qjsonobject_list_to_qvariantlist(v), index); } -void JsonDbCachingListModelPrivate::_q_jsonDbErrorResponse(int, int code, const QString &message) +void JsonDbCachingListModelPrivate::_q_readError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString & message) { Q_Q(JsonDbCachingListModel); qWarning() << QString("JsonDb error: %1 %2").arg(code).arg(message); @@ -947,26 +929,31 @@ void JsonDbCachingListModelPrivate::_q_jsonDbErrorResponse(int, int code, const emit q->errorChanged(q->error()); } -void JsonDbCachingListModelPrivate::_q_dbNotified(const QString ¬ify_uuid, const QtAddOn::JsonDb::JsonDbNotification &_notification) +void JsonDbCachingListModelPrivate::_q_notificationsAvailable() { - if (state == JsonDbCachingListModel::Querying) { - NotifyItem pending; - pending.notifyUuid = notify_uuid; - pending.item = _notification.object(); - pending.action = _notification.action(); - pendingNotifications.append(pending); - } else if (state == JsonDbCachingListModel::Ready) { - sendNotifications(notify_uuid, _notification.object(), _notification.action()); + Q_Q(JsonDbCachingListModel); + QJsonDbWatcher *watcher = qobject_cast<QJsonDbWatcher *>(q->sender()); + int partitionIndex = indexOfWatcher(watcher); + if (!watcher || partitionIndex == -1) + return; + QList<QJsonDbNotification> list = watcher->takeNotifications(); + for (int i = 0; i < list.count(); i++) { + const QJsonDbNotification & notification = list[i]; + QVariantMap object = notification.object().toVariantMap(); + if (state == JsonDbCachingListModel::Querying) { + NotifyItem pending; + pending.partitionIndex = partitionIndex; + pending.item = object; + pending.action = notification.action(); + pendingNotifications.append(pending); + } else if (state == JsonDbCachingListModel::Ready) { + sendNotifications(partitionIndex, object, notification.action()); + } } } -void JsonDbCachingListModelPrivate::_q_dbNotifyReadyResponse(int /* id */, const QVariant &/* result */) -{ -} - -void JsonDbCachingListModelPrivate::_q_dbNotifyErrorResponse(int id, int code, const QString &message) +void JsonDbCachingListModelPrivate::_q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode code, const QString &message) { - Q_UNUSED(id); Q_Q(JsonDbCachingListModel); qWarning() << QString("JsonDbCachingListModel Notification error: %1 %2").arg(code).arg(message); int oldErrorCode = errorCode; @@ -1012,23 +999,52 @@ void JsonDbCachingListModelPrivate::_q_verifyDefaultIndexType(int index) } } +void JsonDbCachingListModelPrivate::appendPartition(JsonDbPartition *v) +{ + Q_Q(JsonDbCachingListModel); + partitionObjects.append(QPointer<JsonDbPartition>(v)); + + partitionObjectDetails.append(RequestInfo()); + ModelRequest *valueRequest = new ModelRequest(); + QObject::connect(valueRequest, SIGNAL(finished(int,QList<QJsonObject>,QString)), + q, SLOT(_q_valueResponse(int,QList<QJsonObject>))); + QObject::connect(valueRequest, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + q, SLOT(_q_readError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + valueRequests.append(valueRequest); + + partitionKeyRequestDetails.append(RequestInfo()); + ModelRequest *keyRequest = new ModelRequest(); + QObject::connect(keyRequest, SIGNAL(finished(int,QList<QJsonObject>,QString)), + q, SLOT(_q_keyResponse(int,QList<QJsonObject>,QString))); + QObject::connect(keyRequest, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + q, SLOT(_q_readError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + keyRequests.append(keyRequest); + + partitionObjectUuids.append(JsonDbModelIndexType()); + + partitionIndexDetails.append(IndexInfo()); + ModelRequest *indexRequest = new ModelRequest(); + QObject::connect(indexRequest, SIGNAL(finished(int,QList<QJsonObject>,QString)), + q, SLOT(_q_indexResponse(int,QList<QJsonObject>))); + QObject::connect(indexRequest, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + q, SLOT(_q_readError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + indexRequests.append(indexRequest); + + if (componentComplete && !query.isEmpty()) { + parseSortOrder(); + createOrUpdateNotification(partitionObjects.count()-1); + if (state == JsonDbCachingListModel::None) + resetModel = true; + fetchIndexSpec(partitionObjects.count()-1); + } +} + void JsonDbCachingListModelPrivate::partitions_append(QQmlListProperty<JsonDbPartition> *p, JsonDbPartition *v) { JsonDbCachingListModel *q = qobject_cast<JsonDbCachingListModel *>(p->object); JsonDbCachingListModelPrivate *pThis = (q) ? q->d_func() : 0; if (pThis) { - pThis->partitionObjects.append(QPointer<JsonDbPartition>(v));\ - pThis->partitionObjectDetails.append(RequestInfo()); - pThis->partitionKeyRequestDetails.append(RequestInfo()); - pThis->partitionObjectUuids.append(JsonDbModelIndexType()); - pThis->partitionIndexDetails.append(IndexInfo()); - if (pThis->componentComplete && !pThis->query.isEmpty()) { - pThis->parseSortOrder(); - pThis->createOrUpdateNotification(pThis->partitionObjects.count()-1); - if (pThis->state == JsonDbCachingListModel::None) - pThis->resetModel = true; - pThis->fetchIndexSpec(pThis->partitionObjects.count()-1); - } + pThis->appendPartition(v); } } @@ -1052,17 +1068,34 @@ JsonDbPartition* JsonDbCachingListModelPrivate::partitions_at(QQmlListProperty<J return 0; } +void JsonDbCachingListModelPrivate::clearPartitions() +{ + partitionObjects.clear(); + partitionObjectDetails.clear(); + partitionKeyRequestDetails.clear(); + partitionObjectUuids.clear(); + partitionIndexDetails.clear(); + while (!keyRequests.isEmpty()) { + delete keyRequests[0]; + keyRequests.removeFirst(); + } + while (!indexRequests.isEmpty()) { + delete indexRequests[0]; + indexRequests.removeFirst(); + } + while (!valueRequests.isEmpty()) { + delete valueRequests[0]; + valueRequests.removeFirst(); + } + reset(); +} + void JsonDbCachingListModelPrivate::partitions_clear(QQmlListProperty<JsonDbPartition> *p) { JsonDbCachingListModel *q = qobject_cast<JsonDbCachingListModel *>(p->object); JsonDbCachingListModelPrivate *pThis = (q) ? q->d_func() : 0; if (pThis) { - pThis->partitionObjects.clear(); - pThis->partitionObjectDetails.clear(); - pThis->partitionKeyRequestDetails.clear(); - pThis->partitionObjectUuids.clear(); - pThis->partitionIndexDetails.clear(); - pThis->reset(); + pThis->clearPartitions(); } } diff --git a/src/imports/jsondb/jsondbcachinglistmodel.h b/src/imports/jsondb/jsondbcachinglistmodel.h index 76b0311a..84f66de9 100644 --- a/src/imports/jsondb/jsondbcachinglistmodel.h +++ b/src/imports/jsondb/jsondbcachinglistmodel.h @@ -53,7 +53,6 @@ #include <QJSValue> #include <QScopedPointer> -#include "jsondb-global.h" #include "jsondbpartition.h" QT_BEGIN_NAMESPACE_JSONDB @@ -121,13 +120,14 @@ private: Q_DISABLE_COPY(JsonDbCachingListModel) Q_DECLARE_PRIVATE(JsonDbCachingListModel) QScopedPointer<JsonDbCachingListModelPrivate> d_ptr; - Q_PRIVATE_SLOT(d_func(), void _q_jsonDbResponse(int, const QVariant&)) - Q_PRIVATE_SLOT(d_func(), void _q_jsonDbErrorResponse(int, int, const QString&)) - Q_PRIVATE_SLOT(d_func(), void _q_dbNotified(QString, QtAddOn::JsonDb::JsonDbNotification)) - Q_PRIVATE_SLOT(d_func(), void _q_dbNotifyReadyResponse(int, QVariant)) - Q_PRIVATE_SLOT(d_func(), void _q_dbNotifyErrorResponse(int, int, QString)) - Q_PRIVATE_SLOT(d_func(), void _q_verifyDefaultIndexType(int)) + Q_PRIVATE_SLOT(d_func(), void _q_verifyDefaultIndexType(int)) + Q_PRIVATE_SLOT(d_func(), void _q_notificationsAvailable()) + Q_PRIVATE_SLOT(d_func(), void _q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode, QString)) + Q_PRIVATE_SLOT(d_func(), void _q_keyResponse(int, QList<QJsonObject>, QString)) + Q_PRIVATE_SLOT(d_func(), void _q_valueResponse(int, QList<QJsonObject>)) + Q_PRIVATE_SLOT(d_func(), void _q_indexResponse(int, QList<QJsonObject>)) + Q_PRIVATE_SLOT(d_func(), void _q_readError(QtJsonDb::QJsonDbRequest::ErrorCode, QString)) }; QT_END_NAMESPACE_JSONDB diff --git a/src/imports/jsondb/jsondbcachinglistmodel_p.h b/src/imports/jsondb/jsondbcachinglistmodel_p.h index bf949dc3..f671dfbf 100644 --- a/src/imports/jsondb/jsondbcachinglistmodel_p.h +++ b/src/imports/jsondb/jsondbcachinglistmodel_p.h @@ -51,7 +51,7 @@ #include <QPointer> #include <QUuid> -#include "jsondb-client.h" +#include "jsondatabase.h" #include "jsondbmodelutils.h" #include "jsondbmodelcache.h" @@ -114,9 +114,11 @@ public: QList<int> cacheMiss; QMap<int, QJSValue> getCallbacks; QList< QPair<int,int> > requestQueue; + QList< QPointer<ModelRequest> >keyRequests; + QList< QPointer<ModelRequest> >indexRequests; + QList< QPointer<ModelRequest> >valueRequests; JsonDbCachingListModel::State state; - JsonDbClient dbClient; QModelIndex parent; int errorCode; QString errorString; @@ -134,8 +136,8 @@ public: void addItem(const QVariantMap &item, int partitionIndex); void deleteItem(const QVariantMap &item, int partitionIndex); void updateItem(const QVariantMap &item, int partitionIndex); - void fillKeys(const QVariant &v, int partitionIndex); - void fillData(const QVariant &v, int partitionIndex); + void fillKeys(const QVariantList &items, int partitionIndex, const QString &sortKey); + void fillData(const QVariantList &items, int partitionIndex); void reset(); void emitDataChanged(int from, int to); @@ -156,13 +158,12 @@ public: void createOrUpdateNotifications(); void parseSortOrder(); void setQueryForSortKeys(); - void verifyIndexSpec(const QVariant &v, int partitionIndex); + void verifyIndexSpec(const QVariantList &items, int partitionIndex); - int indexOfKeyRequestId(int requestId); - int indexOfRequestId(int requestId); - int indexOfNotifyUUID(const QString& notifyUuid); - int indexOfKeyIndexSpecId(int requestId); + int indexOfWatcher(QJsonDbWatcher *watcher); + void appendPartition(JsonDbPartition *v); + void clearPartitions(); QVariant getItem(int index); QVariant getItem(int index, int role); void queueGetCallback(int index, const QJSValue &callback); @@ -172,14 +173,16 @@ public: void set(int index, const QJSValue& valuemap, const QJSValue &successCallback, const QJSValue &errorCallback); - void sendNotifications(const QString& currentNotifyUuid, const QVariant &v, JsonDbClient::NotifyType action); + void sendNotifications(int partitionIndex, const QVariantMap &v, QJsonDbWatcher::Action action); + // private slots - void _q_jsonDbResponse(int , const QVariant &); - void _q_jsonDbErrorResponse(int , int, const QString&); - void _q_dbNotified(const QString ¬ify_uuid, const QtAddOn::JsonDb::JsonDbNotification &_notification); - void _q_dbNotifyReadyResponse(int id, const QVariant &result); - void _q_dbNotifyErrorResponse(int id, int code, const QString &message); void _q_verifyDefaultIndexType(int index); + void _q_notificationsAvailable(); + void _q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode code, const QString &message); + void _q_readError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString & message); + void _q_keyResponse(int , const QList<QJsonObject>&, const QString&); + void _q_valueResponse(int , const QList<QJsonObject>&); + void _q_indexResponse(int , const QList<QJsonObject>&); static void partitions_append(QQmlListProperty<JsonDbPartition> *p, JsonDbPartition *v); static int partitions_count(QQmlListProperty<JsonDbPartition> *p); diff --git a/src/imports/jsondb/jsondbchangessinceobject.cpp b/src/imports/jsondb/jsondbchangessinceobject.cpp index 0872a469..274b1c96 100644 --- a/src/imports/jsondb/jsondbchangessinceobject.cpp +++ b/src/imports/jsondb/jsondbchangessinceobject.cpp @@ -38,10 +38,9 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "jsondb-global.h" #include "jsondbchangessinceobject.h" #include "jsondbpartition.h" -#include "private/jsondb-strings_p.h" +#include <private/qjsondbstrings_p.h> #include <qdebug.h> QT_BEGIN_NAMESPACE_JSONDB @@ -88,7 +87,6 @@ JsonDbChangesSinceObject::JsonDbChangesSinceObject(QObject *parent) , startStateNumber(0) , partitionObject(0) , defaultPartitionObject(0) - , jsondbChangesSince(0) , errorCode(0) , objectStatus(JsonDbChangesSinceObject::Null) { @@ -98,8 +96,8 @@ JsonDbChangesSinceObject::~JsonDbChangesSinceObject() { if (defaultPartitionObject) delete defaultPartitionObject; - if (jsondbChangesSince) - delete jsondbChangesSince; +// if (jsondbChangesSince) +// delete jsondbChangesSince; } @@ -167,8 +165,8 @@ void JsonDbChangesSinceObject::setStateNumber(quint32 newStateNumber) */ quint32 JsonDbChangesSinceObject::startingStateNumber() const { - if (jsondbChangesSince) - return jsondbChangesSince->startingStateNumber(); +// if (jsondbChangesSince) +// return jsondbChangesSince->startingStateNumber(); return startStateNumber; } @@ -179,8 +177,8 @@ quint32 JsonDbChangesSinceObject::startingStateNumber() const */ quint32 JsonDbChangesSinceObject::currentStateNumber() const { - if (jsondbChangesSince) - return jsondbChangesSince->currentStateNumber(); +// if (jsondbChangesSince) +// return jsondbChangesSince->currentStateNumber(); return startStateNumber; } @@ -227,9 +225,9 @@ quint32 JsonDbChangesSinceObject::currentStateNumber() const QVariantList JsonDbChangesSinceObject::takeResults() { QVariantList list; - if (jsondbChangesSince) { - list = jsondbChangesSince->takeResults(); - } +// if (jsondbChangesSince) { +// list = jsondbChangesSince->takeResults(); +// } return list; } @@ -339,8 +337,9 @@ void JsonDbChangesSinceObject::setReadyStatus() emit statusChanged(objectStatus); } -void JsonDbChangesSinceObject::setError(QtAddOn::JsonDb::JsonDbError::ErrorCode code, const QString& message) +void JsonDbChangesSinceObject::setError(/*QtAddOn::JsonDb::JsonDbError::ErrorCode code, */const QString& message) { + int code = 0; int oldErrorCode = errorCode; errorCode = code; errorString = message; @@ -376,28 +375,28 @@ int JsonDbChangesSinceObject::start() return -1; } - if (jsondbChangesSince) { - delete jsondbChangesSince; - } - jsondbChangesSince = partitionObject->jsonDb.changesSince(); - jsondbChangesSince->setTypes(filterTypes); - jsondbChangesSince->setStateNumber(startStateNumber); - jsondbChangesSince->setPartition(partitionObject->name()); - connect(jsondbChangesSince, SIGNAL(resultsReady(int)), - this, SIGNAL(resultsReady(int))); - connect(jsondbChangesSince, SIGNAL(finished()), - this, SLOT(setReadyStatus())); - connect(jsondbChangesSince, SIGNAL(finished()), - this, SIGNAL(finished())); - connect(jsondbChangesSince, SIGNAL(error(QtAddOn::JsonDb::JsonDbError::ErrorCode,QString)), - this, SLOT(setError(QtAddOn::JsonDb::JsonDbError::ErrorCode,QString))); - - jsondbChangesSince->start(); - objectStatus = JsonDbChangesSinceObject::Loading; - emit statusChanged(objectStatus); - - return jsondbChangesSince->requestId(); - +// if (jsondbChangesSince) { +// delete jsondbChangesSince; +// } +// jsondbChangesSince = partitionObject->jsonDb.changesSince(); +// jsondbChangesSince->setTypes(filterTypes); +// jsondbChangesSince->setStateNumber(startStateNumber); +// jsondbChangesSince->setPartition(partitionObject->name()); +// connect(jsondbChangesSince, SIGNAL(resultsReady(int)), +// this, SIGNAL(resultsReady(int))); +// connect(jsondbChangesSince, SIGNAL(finished()), +// this, SLOT(setReadyStatus())); +// connect(jsondbChangesSince, SIGNAL(finished()), +// this, SIGNAL(finished())); +// connect(jsondbChangesSince, SIGNAL(error(QtAddOn::JsonDb::JsonDbError::ErrorCode,QString)), +// this, SLOT(setError(QtAddOn::JsonDb::JsonDbError::ErrorCode,QString))); + +// jsondbChangesSince->start(); +// objectStatus = JsonDbChangesSinceObject::Loading; +// emit statusChanged(objectStatus); + +// return jsondbChangesSince->requestId(); + return -1; } #include "moc_jsondbchangessinceobject.cpp" diff --git a/src/imports/jsondb/jsondbchangessinceobject.h b/src/imports/jsondb/jsondbchangessinceobject.h index 22649af4..f02db491 100644 --- a/src/imports/jsondb/jsondbchangessinceobject.h +++ b/src/imports/jsondb/jsondbchangessinceobject.h @@ -48,7 +48,8 @@ #include <QJSValue> #include <QQmlParserStatus> #include <QQmlListProperty> -#include "jsondb-client.h" +#include <QStringList> +#include <QJsonDbWatcher> QT_BEGIN_NAMESPACE_JSONDB @@ -105,7 +106,7 @@ Q_SIGNALS: void errorChanged(const QVariantMap &newError); private Q_SLOTS: - void setError(QtAddOn::JsonDb::JsonDbError::ErrorCode code, const QString& message); + void setError(/*QtAddOn::JsonDb::JsonDbError::ErrorCode code, */const QString& message); void setReadyStatus(); private: @@ -114,7 +115,7 @@ private: QStringList filterTypes; QPointer<JsonDbPartition> partitionObject; QPointer<JsonDbPartition> defaultPartitionObject; - QPointer<JsonDbChangesSince> jsondbChangesSince; + //QPointer<JsonDbChangesSince> jsondbChangesSince; int errorCode; QString errorString; Status objectStatus; diff --git a/src/imports/jsondb/jsondblistmodel.cpp b/src/imports/jsondb/jsondblistmodel.cpp index 7f184d7b..c22a4f88 100644 --- a/src/imports/jsondb/jsondblistmodel.cpp +++ b/src/imports/jsondb/jsondblistmodel.cpp @@ -41,10 +41,13 @@ #include "jsondblistmodel.h" #include "jsondblistmodel_p.h" -#include "private/jsondb-strings_p.h" +#include "jsondatabase.h" #include <QJSEngine> #include <QJSValueIterator> +#include <QThread> +#include <QString> +#include <qdebug.h> #undef DEBUG_LIST_MODEL @@ -70,33 +73,34 @@ JsonDbListModelPrivate::JsonDbListModelPrivate(JsonDbListModel *q) , cacheStart(0) , cacheEnd(0) , newChunkOffset(0) - , totalCountRequestId(-1) , lastFetchedIndex(-1) , requestInProgress(false) , componentComplete(false) , resetModel(true) - , updateRecieved(false) + , updateReceived(false) , totalRowCountRecieved(false) , state(None) - , jsonDbConnection(JsonDbConnection::instance()) + , errorCode(0) { } void JsonDbListModelPrivate::init() { Q_Q(JsonDbListModel); - q->connect(&jsonDb, SIGNAL(response(int,const QVariant&)), - q, SLOT(_q_jsonDbResponse(int,const QVariant&))); - q->connect(&jsonDb, SIGNAL(error(int,int,const QString&)), - q, SLOT(_q_jsonDbErrorResponse(int,int,const QString&))); + QObject::connect(&valueRequest, SIGNAL(finished(int,QList<QJsonObject>,QString)), + q, SLOT(_q_valueResponse(int,QList<QJsonObject>))); + QObject::connect(&valueRequest, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + q, SLOT(_q_readError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + QObject::connect(&countRequest, SIGNAL(finished(int,QList<QJsonObject>,QString)), + q, SLOT(_q_countResponse(int,QList<QJsonObject>))); + QObject::connect(&countRequest, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + q, SLOT(_q_readError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + } JsonDbListModelPrivate::~JsonDbListModelPrivate() { - // Why do we need to do this while destroying the object - if (!notifyUuid.isEmpty()) { - jsonDb.unregisterNotification(notifyUuid); - } + clearNotification(); } void JsonDbListModelPrivate::clearCache(int newStart) @@ -217,7 +221,6 @@ void JsonDbListModelPrivate::insertItem(const QVariantMap &item, bool emitSignal // When a new item is added, the position of the item is not known // to the model. We will clear the cache and notify that an item // is added at the end + all data is changed. - QModelIndex parent; q->beginInsertRows(parent, totalRowCount-1, totalRowCount-1); q->endInsertRows(); emit q->countChanged(); @@ -239,7 +242,6 @@ void JsonDbListModelPrivate::deleteItem(const QVariantMap &item, bool emitSignal int index = cachedUuids.indexOf(uuid); if (index != -1) { // When item is in the cache emit signals using the exact position. - QModelIndex parent; if (emitSignals) q->beginRemoveRows(parent, cacheStart+index, cacheStart+index); removeItem(index); @@ -253,7 +255,6 @@ void JsonDbListModelPrivate::deleteItem(const QVariantMap &item, bool emitSignal // Model dosen't know the position from where the item is deleted. // We will clear the cache and notify that an item is removed // from the end + all data is changed. - QModelIndex parent; if (!totalRowCount) emitSignals = false; if (emitSignals) @@ -313,17 +314,68 @@ void JsonDbListModelPrivate::_q_requestAnotherChunk(int offset) newChunkOffset = cacheEnd; // now fetch more resetModel = false; - int id = jsonDb.query(query, newChunkOffset, maxItemsToFetch, partitionObject->name()); - requestIds.insert(id); - + QJsonDbReadRequest *request = valueRequest.newRequest(0); + request->setQuery(query); + request->setProperty("queryOffset", newChunkOffset); + request->setQueryLimit(maxItemsToFetch); + request->setPartition(partitionObject->name()); + JsonDatabase::sharedConnection().send(request); requestInProgress = true; } +ModelSyncCall::ModelSyncCall(const QString &_query, int _offset, int _maxItems, + const QString & _partitionName, QVariantList *_data) + : query(_query), + offset(_offset), + maxItems(_maxItems), + partitionName(_partitionName), + data(_data) +{ + +} +ModelSyncCall::~ModelSyncCall() +{ + if (request) + delete request; + if (connection) + delete connection; +} + +void ModelSyncCall::createSyncRequest() +{ + connection = new QJsonDbConnection(); + connection->connectToServer(); + request = new QJsonDbReadRequest; + connect(request, SIGNAL(finished()), this, SLOT(onQueryFinished())); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SLOT(onQueryError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + request->setQuery(query); + request->setProperty("queryOffset", offset); + request->setQueryLimit(maxItems); + request->setPartition(partitionName); + connection->send(request); + //qDebug()<<"createSyncRequest Query :"<<query<<request->property("requestId"); +} + +void ModelSyncCall::onQueryFinished() +{ + *data = qjsonobject_list_to_qvariantlist(request->takeResults()); + //qDebug()<<"onQueryFinished Query :"<<query<<request->property("requestId"); + QThread::currentThread()->quit(); +} + +void ModelSyncCall::onQueryError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message) +{ + qWarning() << QString("JsonDbListModel error: %1 %2").arg(code).arg(message); + QThread::currentThread()->quit(); +} + void JsonDbListModelPrivate::fetchChunkSynchronous(int offset) { // Ignore previous reqests if (requestInProgress) { - requestIds.clear(); + //requestIds.clear(); + valueRequest.resetRequest(); } Q_ASSERT(!query.isEmpty()); int maxItemsToFetch = chunkSize; @@ -337,32 +389,49 @@ void JsonDbListModelPrivate::fetchChunkSynchronous(int offset) // now fetch more resetModel = false; requestInProgress = true; - QVariantMap request = JsonDbConnection::makeQueryRequest(query, newChunkOffset, maxItemsToFetch, - QMap<QString,QVariant>(), partitionObject->name()); - QVariant v = jsonDbConnection->sync(request); + QVariantList resultList; + QThread syncThread; + ModelSyncCall *call = new ModelSyncCall(query, newChunkOffset, maxItemsToFetch, + partitionObject->name(), &resultList); + QObject::connect(&syncThread, SIGNAL(started()), + call, SLOT(createSyncRequest())); + QObject::connect(&syncThread, SIGNAL(finished()), + call, SLOT(deleteLater())); + call->moveToThread(&syncThread); + syncThread.start(); + syncThread.wait(); + updateCache(resultList); requestInProgress = false; - updateCache(v.toMap()); } void JsonDbListModelPrivate::populateModel() { Q_Q(JsonDbListModel); clearCache(); - updateRecieved = false; + updateReceived = false; totalRowCountRecieved = false; totalRowCount = 0; + newChunkOffset = 0; // Request the total count QString countQuery = query+"[count]"; - totalCountRequestId = jsonDb.query(countQuery, 0, -1, partitionObject->name()); - + QJsonDbReadRequest *cRequest = countRequest.newRequest(0); + cRequest->setQuery(countQuery); + cRequest->setPartition(partitionObject->name()); + JsonDatabase::sharedConnection().send(cRequest); + //qDebug()<<"Count Query :"<<countQuery<<cRequest->property("requestId"); //Request at least 2 chunks of data int itemsToGet = chunkSize*2; if (maxCacheSize) itemsToGet = qMin(itemsToGet, maxCacheSize); resetModel = true; - - int id = jsonDb.query(query, newChunkOffset, itemsToGet, partitionObject->name()); - requestIds.insert(id); + QJsonDbReadRequest *request = valueRequest.newRequest(0); + request->setQuery(query); + request->setProperty("queryOffset", newChunkOffset); //TODO change newChunkOffset to 0 + request->setQueryLimit(itemsToGet); + request->setPartition(partitionObject->name()); + JsonDatabase::sharedConnection().send(request); + //qDebug()<<"Query :"<<query<<request->property("requestId")<<newChunkOffset; + createOrUpdateNotification(); requestInProgress = true; state = JsonDbListModelPrivate::Querying; emit q->stateChanged(); @@ -515,24 +584,28 @@ void JsonDbListModel::componentComplete() d->populateModel(); } -void JsonDbListModelPrivate::createOrUpdateNotification() +void JsonDbListModelPrivate::clearNotification() { - Q_Q(JsonDbListModel); - - if (!notifyUuid.isEmpty()) { - jsonDb.unregisterNotification(notifyUuid); - notifyUuid.clear(); + if (watcher) { + JsonDatabase::sharedConnection().removeWatcher(watcher); + delete watcher; + watcher = 0; } +} - JsonDbClient::NotifyTypes notifyActions = JsonDbClient::NotifyCreate - | JsonDbClient::NotifyUpdate| JsonDbClient::NotifyRemove; - - notifyUuid = jsonDb.registerNotification( - notifyActions , query, partitionObject->name(), - q, SLOT(_q_dbNotified(QString,QtAddOn::JsonDb::JsonDbNotification)), - q, SLOT(_q_dbNotifyReadyResponse(int,QVariant)), - SLOT(_q_dbNotifyErrorResponse(int,int,QString))); - +void JsonDbListModelPrivate::createOrUpdateNotification() +{ + Q_Q(JsonDbListModel); + clearNotification(); + watcher = new QJsonDbWatcher(); + watcher->setQuery(query); + watcher->setWatchedActions(QJsonDbWatcher::Created | QJsonDbWatcher::Updated |QJsonDbWatcher::Removed); + watcher->setPartition(partitionObject->name()); + QObject::connect(watcher, SIGNAL(notificationsAvailable(int)), + q, SLOT(_q_notificationsAvailable())); + QObject::connect(watcher, SIGNAL(error(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)), + q, SLOT(_q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString))); + JsonDatabase::sharedConnection().addWatcher(watcher); } int JsonDbListModel::sectionIndex(const QString §ion, @@ -540,20 +613,69 @@ int JsonDbListModel::sectionIndex(const QString §ion, const QJSValue &errorCallback) { Q_D(JsonDbListModel); + if (!successCallback.isCallable()) { + qWarning("JsonDbListModel Cannot call sectionIndex without a success callbak function"); + return -1; + } // Find the count of items "< section" QString sectionCountQueryLT = d->queryWithoutSort+"[?"+d->orderProperties[0]+"<\""+section+"\"][count]"; - int id = d->jsonDb.query(sectionCountQueryLT, 0, -1, d->partitionObject->name()); - // Register any valid callbacks + + QJsonDbReadRequest *request = new QJsonDbReadRequest(); + connect(request, SIGNAL(finished()), this, SLOT(_q_sectionIndexResponse())); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SLOT(_q_sectionIndexError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + request->setQuery(sectionCountQueryLT); + request->setPartition(d->partitionObject->name()); + JsonDatabase::sharedConnection().send(request); + int id = request->property("requestId").toInt(); CallbackInfo info; - if (successCallback.isCallable() - || errorCallback.isCallable()) { - info.successCallback = successCallback; - info.errorCallback = errorCallback; - d->sectionIndexRequestIds.insert(id, info); - } + info.successCallback = successCallback; + info.errorCallback = errorCallback; + d->sectionIndexCallbacks.insert(request, info); return id; } +void JsonDbListModelPrivate::_q_sectionIndexResponse() +{ + Q_Q(JsonDbListModel); + QJsonDbReadRequest *request = qobject_cast<QJsonDbReadRequest*>(q->sender()); + if (request) { + QList<QJsonObject> v = request->takeResults(); + if (v.count()) { + int id = request->property("requestId").toInt(); + int count = (int) v[0].value(QStringLiteral("count")).toDouble(); + CallbackInfo info = sectionIndexCallbacks.value(request); + if (info.successCallback.isCallable()) { + QJSValueList args; + args << info.successCallback.engine()->toScriptValue(id); + args << info.successCallback.engine()->toScriptValue(count); + info.successCallback.call(args); + } + } + sectionIndexCallbacks.remove(request); + request->deleteLater(); + } +} + +void JsonDbListModelPrivate::_q_sectionIndexError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message) +{ + Q_Q(JsonDbListModel); + QJsonDbReadRequest *request = qobject_cast<QJsonDbReadRequest*>(q->sender()); + if (request) { + int id = request->property("requestId").toInt(); + CallbackInfo info = sectionIndexCallbacks.value(request); + if (info.errorCallback.isCallable()) { + QJSValueList args; + args << info.successCallback.engine()->toScriptValue(id); + args << info.successCallback.engine()->toScriptValue(int(code)); + args << info.successCallback.engine()->toScriptValue(message); + info.errorCallback.call(args); + } + sectionIndexCallbacks.remove(request); + request->deleteLater(); + } +} + int JsonDbListModel::count() const { Q_D(const JsonDbListModel); @@ -638,17 +760,7 @@ void JsonDbListModelPrivate::set(int index, const QJSValue& valuemap, lastFetchedItem.clear(); lastFetchedIndex = -1; - // Item will be updated through the update notification - CallbackInfo info; - info.index = index; - int id = jsonDb.update(item, partitionObject->name()); // possibly change to variantToQson(item).. - // Register any valid callbacks - if (successCallback.isCallable() - || errorCallback.isCallable()) { - info.successCallback = successCallback; - info.errorCallback = errorCallback; - updateRequestIds.insert(id, info); - } + update(index, item, successCallback, errorCallback); } void JsonDbListModel::setProperty(int index, const QString& property, const QVariant& value, @@ -689,18 +801,61 @@ void JsonDbListModelPrivate::setProperty(int index, const QString& property, con lastFetchedItem.clear(); lastFetchedIndex = -1; + update(index, item, successCallback, errorCallback); +} + +void JsonDbListModelPrivate::update(int index, const QVariantMap &item, + const QJSValue &successCallback, const QJSValue &errorCallback) +{ + Q_Q(JsonDbListModel); + QJsonDbUpdateRequest *request = new QJsonDbUpdateRequest(QJsonObject::fromVariantMap(item)); + QObject::connect(request, SIGNAL(finished()), q, SLOT(_q_updateResponse())); + QObject::connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + q, SLOT(_q_updateError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + request->setPartition(partitionObject->name()); + JsonDatabase::sharedConnection().send(request); + CallbackInfo info; + info.index = index; + info.successCallback = successCallback; + info.errorCallback = errorCallback; + updateCallbacks.insert(request, info); +} - int id = jsonDb.update(item, partitionObject->name()); // possibly change to variantToQson(item).. - // Register any valid callbacks - if (successCallback.isCallable() - || errorCallback.isCallable()) { - - // Item will be updated through the update notification - CallbackInfo info; - info.index = index; - info.successCallback = successCallback; - info.errorCallback = errorCallback; - updateRequestIds.insert(id, info); +void JsonDbListModelPrivate::_q_updateResponse() +{ + Q_Q(JsonDbListModel); + QJsonDbWriteRequest *request = qobject_cast<QJsonDbWriteRequest*>(q->sender()); + if (request) { + int id = request->property("requestId").toInt(); + CallbackInfo info = updateCallbacks.value(request); + if (info.successCallback.isCallable()) { + QJSValueList args; + args << info.successCallback.engine()->toScriptValue(id); + args << info.successCallback.engine()->toScriptValue(info.index); + info.successCallback.call(args); + } + } + updateCallbacks.remove(request); + request->deleteLater(); +} + +void JsonDbListModelPrivate::_q_updateError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message) +{ + Q_Q(JsonDbListModel); + QJsonDbWriteRequest *request = qobject_cast<QJsonDbWriteRequest*>(q->sender()); + if (request) { + int id = request->property("requestId").toInt(); + CallbackInfo info = updateCallbacks.value(request); + if (info.errorCallback.isCallable()) { + QJSValueList args; + args << info.successCallback.engine()->toScriptValue(id); + args << info.successCallback.engine()->toScriptValue(info.index); + args << info.successCallback.engine()->toScriptValue(int(code)); + args << info.successCallback.engine()->toScriptValue(message); + info.errorCallback.call(args); + } + updateCallbacks.remove(request); + request->deleteLater(); } } @@ -963,94 +1118,66 @@ int JsonDbListModel::roleFromString(const QString &roleName) const return d->roleNames.key(roleName.toLatin1(), -1); } -void JsonDbListModelPrivate::updateCache(const QVariantMap &m) +void JsonDbListModelPrivate::updateCache(const QVariantList &items) { Q_Q(JsonDbListModel); - if (m.contains("data")) { - QVariantList items = m.value(QLatin1String("data")).toList(); - int size = items.size(); - int sizeAdded = 0; - if (size) { - DEBUG()<<"OLD Cache Start"<<cacheStart<<"Cache End:"<<cacheEnd; - if (resetModel) - q->beginResetModel(); - makeSpaceFor(size, newChunkOffset); - bool appendToCache = (newChunkOffset >= cacheEnd) ? true : false; - int insertAt = appendToCache ? itemsInCache() : 0; - DEBUG()<<"INSERT AT :"<<insertAt<<"Elements Retrieved:"<<size<<"ChunkOffset:"<<newChunkOffset<<appendToCache << itemsInCache(); - DEBUG()<<"Cache Start"<<cacheStart<<"Cache End:"<<cacheEnd<<"Total Rows = "<<totalRowCount; - // Add the new result to cache. - for (int i = 0; i < size; i++) { - QVariantMap item = items.at(i).toMap(); - const QString &uuid = item.value(JsonDbString::kUuidStr).toString(); - if (objectSortValues.contains(uuid)){ - break; - } - JsonDbSortKey key = sortKey(item); - objectUuids.insert(key, uuid); - objectSortValues.insert(uuid, key); - data[uuid] = item; - cachedUuids.insert(insertAt++, uuid); - sizeAdded++; + int size = items.size(); + int sizeAdded = 0; + if (size) { + DEBUG()<<"OLD Cache Start"<<cacheStart<<"Cache End:"<<cacheEnd; + if (resetModel) + q->beginResetModel(); + makeSpaceFor(size, newChunkOffset); + bool appendToCache = (newChunkOffset >= cacheEnd) ? true : false; + int insertAt = appendToCache ? itemsInCache() : 0; + DEBUG()<<"INSERT AT :"<<insertAt<<"Elements Retrieved:"<<size<<"ChunkOffset:"<<newChunkOffset<<appendToCache << itemsInCache(); + DEBUG()<<"Cache Start"<<cacheStart<<"Cache End:"<<cacheEnd<<"Total Rows = "<<totalRowCount; + // Add the new result to cache. + for (int i = 0; i < size; i++) { + QVariantMap item = items.at(i).toMap(); + const QString &uuid = item.value(QStringLiteral("_uuid")).toString(); + if (objectSortValues.contains(uuid)){ + break; } - DEBUG()<<"sizeAdded:"<<sizeAdded; - // Update the cache limits - if (!itemsInCache()) { - cacheStart = newChunkOffset; - cacheEnd = cacheStart + sizeAdded; - } else if (appendToCache) { - cacheEnd += sizeAdded; - } else { - cacheStart = qMax(0, cacheStart-sizeAdded); - } - Q_ASSERT(cachedUuids.count() == data.count()); + JsonDbSortKey key = sortKey(item); + objectUuids.insert(key, uuid); + objectSortValues.insert(uuid, key); + data[uuid] = item; + cachedUuids.insert(insertAt++, uuid); + sizeAdded++; } - if (resetModel && totalRowCountRecieved) - resetModelFinished(); - else - updateRecieved = true; + DEBUG()<<"sizeAdded:"<<sizeAdded; + // Update the cache limits + if (!itemsInCache()) { + cacheStart = newChunkOffset; + cacheEnd = cacheStart + sizeAdded; + } else if (appendToCache) { + cacheEnd += sizeAdded; + } else { + cacheStart = qMax(0, cacheStart-sizeAdded); + } + Q_ASSERT(cachedUuids.count() == data.count()); } + if (resetModel && totalRowCountRecieved) + resetModelFinished(); + else + updateReceived = true; } -void JsonDbListModelPrivate::_q_jsonDbResponse(int id, const QVariant &v) +void JsonDbListModelPrivate::_q_valueResponse(int, const QList<QJsonObject> &v) { - if (requestIds.contains(id)) { - requestIds.remove(id); - requestInProgress = false; - updateCache(v.toMap()); - } else if (totalCountRequestId == id) { - QVariantMap m = v.toMap(); - QVariantList items = m.value(QLatin1String("data")).toList(); - m = items.at(0).toMap(); - totalRowCount = m.value(QLatin1String("count")).toInt(); + requestInProgress = false; + updateCache(qjsonobject_list_to_qvariantlist(v)); +} + +void JsonDbListModelPrivate::_q_countResponse(int, const QList<QJsonObject> &v) +{ + if (v.count()) { + totalRowCount = (int) v[0].value(QStringLiteral("count")).toDouble(); totalRowCountRecieved = true; - if (updateRecieved) + + if (updateReceived) resetModelFinished(); - } else if (updateRequestIds.constFind(id) != updateRequestIds.constEnd()) { - CallbackInfo info = updateRequestIds.value(id); - if (info.successCallback.isCallable()) { - QJSValueList args; - QJSValue scriptResult = info.successCallback.engine()->toScriptValue(id); - args << scriptResult; - scriptResult = info.successCallback.engine()->toScriptValue(info.index); - args << scriptResult; - info.successCallback.call(args); - } - updateRequestIds.remove(id); - } else if (sectionIndexRequestIds.constFind(id) != sectionIndexRequestIds.constEnd()) { - CallbackInfo info = sectionIndexRequestIds.value(id); - if (info.successCallback.isCallable()) { - QVariantMap m = v.toMap(); - QVariantList items = m.value(QLatin1String("data")).toList(); - m = items.at(0).toMap(); - QJSValueList args; - QJSValue scriptResult = info.successCallback.engine()->toScriptValue(id); - args << scriptResult; - scriptResult = info.successCallback.engine()->toScriptValue(m.value(QLatin1String("count")).toInt()); - args << scriptResult; - info.successCallback.call(args); - } - sectionIndexRequestIds.remove(id); } } @@ -1063,8 +1190,12 @@ void JsonDbListModelPrivate::resetModelFinished() state = Ready; emit q->stateChanged(); resetModel = false; + for (int i = 0; i<pendingNotifications.size(); i++) { + const NotifyItem &pending = pendingNotifications[i]; + sendNotifications(pending.item, pending.action); + } pendingNotifications.clear(); - createOrUpdateNotification(); + //createOrUpdateNotification(); } bool operator<(const QVariant& a, const QVariant& b) @@ -1105,62 +1236,55 @@ bool JsonDbListModelPrivate::findSortOrder() return true; } -void JsonDbListModelPrivate::_q_dbNotified(const QString ¬ify_uuid, const QtAddOn::JsonDb::JsonDbNotification &_notification) +void JsonDbListModelPrivate::_q_notificationsAvailable() { - if (notify_uuid != notifyUuid) { - return; - } - if (resetModel) { - NotifyItem pending; - pending.notifyUuid = notify_uuid; - pending.item = _notification.object(); - pending.action = _notification.action(); - pendingNotifications.append(pending); - } else { - sendNotifications(_notification.object(), _notification.action()); + QList<QJsonDbNotification> list = watcher->takeNotifications(); + for (int i = 0; i < list.count(); i++) { + const QJsonDbNotification & notification = list[i]; + QVariantMap object = notification.object().toVariantMap(); + if (resetModel) { + NotifyItem pending; + pending.item = object; + pending.action = notification.action(); + pendingNotifications.append(pending); + } else { + //qDebug()<<"Notify "<<object<<notification.action(); + sendNotifications(object, notification.action()); + } } } -void JsonDbListModelPrivate::sendNotifications(const QVariant &v, JsonDbClient::NotifyType action) +void JsonDbListModelPrivate::sendNotifications(const QVariantMap &v, QJsonDbWatcher::Action action) { - const QVariantMap &item = v.toMap(); - if (action == JsonDbClient::NotifyCreate) { - insertItem(item); - } else if (action == JsonDbClient::NotifyRemove) { - deleteItem(item); - } else if (action == JsonDbClient::NotifyUpdate) { - updateItem(item); + if (action == QJsonDbWatcher::Created) { + insertItem(v); + } else if (action == QJsonDbWatcher::Removed) { + deleteItem(v); + } else if (action == QJsonDbWatcher::Updated) { + updateItem(v); } } -void JsonDbListModelPrivate::_q_dbNotifyReadyResponse(int /* id */, const QVariant &/* result */) +void JsonDbListModelPrivate::_q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode code, const QString &message) { -} - -void JsonDbListModelPrivate::_q_dbNotifyErrorResponse(int id, int code, const QString &message) -{ - Q_UNUSED(id); + Q_Q(JsonDbListModel); qWarning() << QString("JsonDbListModel Notification error: %1 %2").arg(code).arg(message); + int oldErrorCode = errorCode; + errorCode = code; + errorString = message; + if (oldErrorCode != errorCode) + emit q->errorChanged(q->error()); } - -void JsonDbListModelPrivate::_q_jsonDbErrorResponse(int id, int code, const QString &message) +void JsonDbListModelPrivate::_q_readError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString & message) { - if (requestIds.contains(id)) { - requestIds.remove(id); - qWarning() << QString("JsonDb error: %1 %2").arg(code).arg(message); - } else if (updateRequestIds.constFind(id) != updateRequestIds.constEnd()) { - CallbackInfo info = updateRequestIds.value(id); - if (info.errorCallback.isCallable()) { - QJSValueList args; - args << info.errorCallback.engine()->toScriptValue(id); - args << info.errorCallback.engine()->toScriptValue(info.index); - args << info.errorCallback.engine()->toScriptValue(code); - args << info.errorCallback.engine()->toScriptValue(message); - info.errorCallback.call(args); - } - updateRequestIds.remove(id); - } + Q_Q(JsonDbListModel); + qWarning() << QString("JsonDbListModel error: %1 %2").arg(code).arg(message); + int oldErrorCode = errorCode; + errorCode = code; + errorString = message; + if (oldErrorCode != errorCode) + emit q->errorChanged(q->error()); } /*! @@ -1175,10 +1299,31 @@ QVariant JsonDbListModel::get(int idx, const QString &property) const int role = roleFromString(property); if (role >= 0) return data(index(idx, 0), role); - else + else { + qDebug()<<"JsonDbListModel::get Invalid role"; return QVariant(); + } } +/*! + \qmlproperty object QtJsonDb::JsonDbListModel::error + \readonly + + This property holds the current error information for the object. It contains: + \list + \o error.code - code for the current error. + \o error.message - detailed explanation of the error + \endlist +*/ + +QVariantMap JsonDbListModel::error() const +{ + Q_D(const JsonDbListModel); + QVariantMap errorMap; + errorMap.insert(QLatin1String("code"), d->errorCode); + errorMap.insert(QLatin1String("message"), d->errorString); + return errorMap; +} class JsonDbSortKeyPrivate : public QSharedData { public: diff --git a/src/imports/jsondb/jsondblistmodel.h b/src/imports/jsondb/jsondblistmodel.h index 36494e6b..a054b52c 100644 --- a/src/imports/jsondb/jsondblistmodel.h +++ b/src/imports/jsondb/jsondblistmodel.h @@ -52,7 +52,7 @@ #include <QJSValue> #include <QScopedPointer> -#include "jsondb-global.h" +#include <QJsonDbReadRequest> #include "jsondbpartition.h" QT_BEGIN_NAMESPACE_JSONDB @@ -92,6 +92,7 @@ public: Q_PROPERTY(int lowWaterMark READ lowWaterMark WRITE setLowWaterMark) Q_PROPERTY(QVariant roleNames READ scriptableRoleNames WRITE setScriptableRoleNames) Q_PROPERTY(JsonDbPartition* partition READ partition WRITE setPartition) + Q_PROPERTY(QVariantMap error READ error NOTIFY errorChanged) virtual void classBegin(); virtual void componentComplete(); @@ -136,11 +137,13 @@ public: const QJSValue &errorCallback = QJSValue(QJSValue::UndefinedValue)); Q_INVOKABLE int sectionIndex(const QString §ion, const QJSValue &successCallback = QJSValue(QJSValue::UndefinedValue), const QJSValue &errorCallback = QJSValue(QJSValue::UndefinedValue)); + QVariantMap error() const; signals: void stateChanged() const; void countChanged() const; void rowCountChanged() const; + void errorChanged(QVariantMap newError); private Q_SLOTS: void partitionNameChanged(const QString &partitionName); @@ -149,15 +152,39 @@ private: Q_DISABLE_COPY(JsonDbListModel) Q_DECLARE_PRIVATE(JsonDbListModel) QScopedPointer<JsonDbListModelPrivate> d_ptr; - Q_PRIVATE_SLOT(d_func(), void _q_jsonDbResponse(int, const QVariant&)) - Q_PRIVATE_SLOT(d_func(), void _q_jsonDbErrorResponse(int, int, const QString&)) Q_PRIVATE_SLOT(d_func(), void _q_requestAnotherChunk(int)) - Q_PRIVATE_SLOT(d_func(), void _q_dbNotified(QString, QtAddOn::JsonDb::JsonDbNotification)) - Q_PRIVATE_SLOT(d_func(), void _q_dbNotifyReadyResponse(int, QVariant)) - Q_PRIVATE_SLOT(d_func(), void _q_dbNotifyErrorResponse(int, int, QString)) + Q_PRIVATE_SLOT(d_func(), void _q_notificationsAvailable()) + Q_PRIVATE_SLOT(d_func(), void _q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode, QString)) + Q_PRIVATE_SLOT(d_func(), void _q_valueResponse(int, QList<QJsonObject>)) + Q_PRIVATE_SLOT(d_func(), void _q_countResponse(int, QList<QJsonObject>)) + Q_PRIVATE_SLOT(d_func(), void _q_readError(QtJsonDb::QJsonDbRequest::ErrorCode, QString)) + Q_PRIVATE_SLOT(d_func(), void _q_sectionIndexResponse()) + Q_PRIVATE_SLOT(d_func(), void _q_sectionIndexError(QtJsonDb::QJsonDbRequest::ErrorCode, QString)) + Q_PRIVATE_SLOT(d_func(), void _q_updateResponse()) + Q_PRIVATE_SLOT(d_func(), void _q_updateError(QtJsonDb::QJsonDbRequest::ErrorCode, QString)) }; +class ModelSyncCall : public QObject +{ + Q_OBJECT +public: + ModelSyncCall(const QString &_query, int _offset, int _maxItems, const QString & _partitionName, QVariantList *_data); + ~ModelSyncCall(); +public Q_SLOTS: + void createSyncRequest(); + void onQueryFinished(); + void onQueryError(QtJsonDb::QJsonDbRequest::ErrorCode, const QString&); +private: + QString query; + int offset; + int maxItems; + QString partitionName; + QVariantList *data; + QPointer<QJsonDbConnection> connection; + QPointer<QJsonDbReadRequest> request; +}; + QT_END_NAMESPACE_JSONDB #endif diff --git a/src/imports/jsondb/jsondblistmodel_p.h b/src/imports/jsondb/jsondblistmodel_p.h index fd773b86..7852fa44 100644 --- a/src/imports/jsondb/jsondblistmodel_p.h +++ b/src/imports/jsondb/jsondblistmodel_p.h @@ -49,8 +49,10 @@ #include <QStringList> #include <QPointer> -#include "jsondb-client.h" -#include "private/jsondb-connection_p.h" + +#include <QJsonDbWatcher> +#include <QJsonDbReadRequest> +#include <QJsonDbUpdateRequest> #include "jsondbmodelutils.h" QT_BEGIN_NAMESPACE_JSONDB @@ -72,10 +74,8 @@ public: int cacheEnd; int newChunkOffset; - QSet<int> requestIds; - QMap<int, CallbackInfo> updateRequestIds; - QMap<int, CallbackInfo> sectionIndexRequestIds; - int totalCountRequestId; + QMap< QPointer<QJsonDbWriteRequest>, CallbackInfo> updateCallbacks; + QMap< QPointer<QJsonDbReadRequest>, CallbackInfo> sectionIndexCallbacks; QHash<QString,QVariantMap> data; // cache that holds all the items. QMultiMap<JsonDbSortKey,QString> objectUuids; // sort value -> uuid @@ -94,15 +94,17 @@ public: bool requestInProgress; bool componentComplete; bool resetModel; - bool updateRecieved; + bool updateReceived; bool totalRowCountRecieved; - QString notifyUuid; QVariantMap roleMap; QHash<int,QByteArray> roleNames; QHash<int,QStringList> properties; QList<NotifyItem> pendingNotifications; + ModelRequest valueRequest; + ModelRequest countRequest; + QPointer<QJsonDbWatcher> watcher; enum State { None, @@ -110,9 +112,9 @@ public: Ready }; State state; - - JsonDbClient jsonDb; - JsonDbConnection *jsonDbConnection; + QModelIndex parent; + int errorCode; + QString errorString; public: JsonDbListModelPrivate(JsonDbListModel *q); @@ -130,26 +132,31 @@ public: QVariantMap getItem(const QModelIndex &modelIndex, int role, bool handleCacheMiss, bool &cacheMiss); void set(int index, const QJSValue& valuemap, const QJSValue &successCallback, const QJSValue &errorCallback); - void setProperty(int index, const QString& property, const QVariant& value, const QJSValue &successCallback, - const QJSValue &errorCallback); + void setProperty(int index, const QString& property, const QVariant& value, + const QJSValue &successCallback, const QJSValue &errorCallback); void fetchChunkSynchronous(int offset); - void updateCache(const QVariantMap &v); + void updateCache(const QVariantList &items); void resetModelFinished(); - - // private slots - void _q_jsonDbResponse(int , const QVariant &); - void _q_jsonDbNotified(const QString&, const QVariant &, const QString &); - void _q_jsonDbErrorResponse(int , int, const QString&); + void update(int index, const QVariantMap &item, + const QJSValue &successCallback, const QJSValue &errorCallback); void _q_requestAnotherChunk(int offset); - void _q_dbNotified(const QString ¬ify_uuid, const QtAddOn::JsonDb::JsonDbNotification &_notification); - void _q_dbNotifyReadyResponse(int /* id */, const QVariant &/* result */); - void _q_dbNotifyErrorResponse(int id, int code, const QString &message); - void sendNotifications(const QVariant &v, JsonDbClient::NotifyType action); + void _q_notificationsAvailable(); + void _q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode code, const QString &message); + void _q_valueResponse(int , const QList<QJsonObject>&); + void _q_countResponse(int , const QList<QJsonObject>&); + void _q_readError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString & message); + void _q_sectionIndexResponse(); + void _q_sectionIndexError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString & message); + void _q_updateResponse(); + void _q_updateError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString & message); + + void sendNotifications(const QVariantMap &v, QJsonDbWatcher::Action action); void populateModel(); + void clearNotification(); void createOrUpdateNotification(); bool findSortOrder(); diff --git a/src/imports/jsondb/jsondbmodelutils.cpp b/src/imports/jsondb/jsondbmodelutils.cpp index 0e6f124a..f86f2eb9 100644 --- a/src/imports/jsondb/jsondbmodelutils.cpp +++ b/src/imports/jsondb/jsondbmodelutils.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "jsondbmodelutils.h" +#include <qdebug.h> QT_BEGIN_NAMESPACE_JSONDB @@ -59,6 +60,11 @@ SortingKey::SortingKey(int partitionIndex, const QVariantList &object, const QLi d = new SortingKeyPrivate(partitionIndex, uuid, directions, values, spec); } +SortingKey::SortingKey(int partitionIndex, const QByteArray &uuid, const QVariantList &object, const QList<bool> &directions, const SortIndexSpec &spec) +{ + d = new SortingKeyPrivate(partitionIndex, uuid, directions, object, spec); +} + SortingKey::SortingKey(const SortingKey &other) :d(other.d) { @@ -117,7 +123,7 @@ bool SortingKey::operator <(const SortingKey &rhs) const // In case of even score jsondb sorts according to _uuid in the same direction as the last sort item if (nKeys) return (dLhs->directions[nKeys-1] ? (cmp < 0) : (cmp > 0)); - return cmp; + return (cmp < 0); } bool SortingKey::operator ==(const SortingKey &rhs) const @@ -204,4 +210,43 @@ QString removeArrayOperator(QString propertyName) return propertyName; } + +ModelRequest::ModelRequest(QObject *parent) + :QObject(parent) +{ +} + +ModelRequest::~ModelRequest() +{ + resetRequest(); +} + +QJsonDbReadRequest* ModelRequest::newRequest(int newIndex) +{ + resetRequest(); + index = newIndex; + request = new QJsonDbReadRequest(); + connect(request, SIGNAL(finished()), this, SLOT(onQueryFinished())); + connect(request, SIGNAL(finished()), request, SLOT(deleteLater())); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + request, SLOT(deleteLater())); + return request; +} + +void ModelRequest::resetRequest() +{ + if (request) { + delete request; + request = 0; + } +} + +void ModelRequest::onQueryFinished() +{ + emit finished(index, request->takeResults(), request->sortKey()); +} + +#include "moc_jsondbmodelutils.cpp" QT_END_NAMESPACE_JSONDB diff --git a/src/imports/jsondb/jsondbmodelutils.h b/src/imports/jsondb/jsondbmodelutils.h index 48ac8c39..85d84519 100644 --- a/src/imports/jsondb/jsondbmodelutils.h +++ b/src/imports/jsondb/jsondbmodelutils.h @@ -39,7 +39,6 @@ ** ****************************************************************************/ - #ifndef JSONDBMODELUTILS_H #define JSONDBMODELUTILS_H #include <QSharedData> @@ -47,7 +46,9 @@ #include <QUuid> #include <QJSValue> #include <QVariant> -#include "jsondb-client.h" +#include <QPointer> +#include <QJsonDbWatcher> +#include <QJsonDbReadRequest> QT_BEGIN_NAMESPACE_JSONDB @@ -58,9 +59,9 @@ struct CallbackInfo { }; struct NotifyItem { - QString notifyUuid; - QVariant item; - JsonDbClient::NotifyType action; + int partitionIndex; + QVariantMap item; + QJsonDbWatcher::Action action; }; struct SortIndexSpec @@ -82,6 +83,29 @@ struct SortIndexSpec {} }; +class JsonDbListModelPrivate; +class ModelRequest : public QObject +{ + friend class JsonDbListModelPrivate; + Q_OBJECT +public: + + ModelRequest(QObject *parent = 0); + ~ModelRequest(); + + QJsonDbReadRequest* newRequest(int newIndex); + void resetRequest(); +Q_SIGNALS: + void finished(int index, const QList<QJsonObject> &items, const QString &sortKey); + void error(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message); + +private Q_SLOTS: + void onQueryFinished(); + +private: + QPointer<QJsonDbReadRequest> request; + int index; +}; struct IndexInfo { @@ -102,6 +126,7 @@ class SortingKey { public: SortingKey(int partitionIndex, const QVariantMap &object, const QList<bool> &directions, const QList<QStringList> &paths, const SortIndexSpec &spec = SortIndexSpec()); SortingKey(int partitionIndex, const QVariantList &object, const QList<bool> &directions, const SortIndexSpec &spec = SortIndexSpec()); + SortingKey(int partitionIndex, const QByteArray &uuid, const QVariantList &object, const QList<bool> &directions, const SortIndexSpec &spec = SortIndexSpec()); SortingKey(const SortingKey&); SortingKey() {} int partitionIndex() const; @@ -113,20 +138,21 @@ private: struct RequestInfo { - int requestId; int lastOffset; - QString notifyUuid; int lastSize; int requestCount; + QPointer<QJsonDbWatcher> watcher; RequestInfo() { clear();} void clear() { - requestId = -1; lastOffset = 0; lastSize = -1; requestCount = 0; - notifyUuid.clear(); + if (watcher) { + delete watcher; + watcher = 0; + } } }; @@ -168,6 +194,8 @@ template <typename T> int iterator_position(T &begin, T &end, T &value) QVariant lookupProperty(QVariantMap object, const QStringList &path); QString removeArrayOperator(QString propertyName); +QList<QJsonObject> qvariantlist_to_qjsonobject_list(const QVariantList &list); +QVariantList qjsonobject_list_to_qvariantlist(const QList<QJsonObject> &list); QT_END_NAMESPACE_JSONDB diff --git a/src/imports/jsondb/jsondbnotification.cpp b/src/imports/jsondb/jsondbnotification.cpp index f55b6075..65d74d70 100644 --- a/src/imports/jsondb/jsondbnotification.cpp +++ b/src/imports/jsondb/jsondbnotification.cpp @@ -38,11 +38,10 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "jsondb-global.h" #include "jsondbnotification.h" #include "jsondbpartition.h" -#include "private/jsondb-strings_p.h" #include "plugin.h" +#include <QJsonDbNotification> #include <qdebug.h> QT_BEGIN_NAMESPACE_JSONDB @@ -118,6 +117,10 @@ JsonDbNotify::JsonDbNotify(QObject *parent) JsonDbNotify::~JsonDbNotify() { + if (partitionObject && active && watcher) + partitionObject->removeNotification(this); + if (watcher) + delete watcher; if (defaultPartitionObject) delete defaultPartitionObject; } @@ -347,11 +350,32 @@ void JsonDbNotify::init() } if (partitionObject && active) { // remove the current notification - partitionObject->removeNotification(this); + if (watcher) { + partitionObject->removeNotification(this); + delete watcher; + } + watcher = new QJsonDbWatcher(); + watcher->setQuery(queryString); + QJsonDbWatcher::Actions actions; + if (actionsList.isEmpty()) { + actions = QJsonDbWatcher::Created | QJsonDbWatcher::Updated |QJsonDbWatcher::Removed; + } else { + if (actionsList.contains(JsonDbNotify::Create)) + actions |= QJsonDbWatcher::Created; + if (actionsList.contains(JsonDbNotify::Update)) + actions |= QJsonDbWatcher::Updated; + if (actionsList.contains(JsonDbNotify::Remove)) + actions |= QJsonDbWatcher::Removed; + } + watcher->setWatchedActions(actions); + watcher->setPartition(partitionObject->name()); + QObject::connect(watcher, SIGNAL(notificationsAvailable(int)), + this, SLOT(onNotificationsAvailable())); + QObject::connect(watcher, SIGNAL(statusChanged(QtJsonDb::QJsonDbWatcher::Status)), + this, SLOT(onStatusChanged(QtJsonDb::QJsonDbWatcher::Status))); + QObject::connect(watcher, SIGNAL(error(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)), + this, SLOT(onNotificationError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString))); partitionObject->updateNotification(this); - objectStatus = JsonDbNotify::Registering; - if (objectStatus != oldStatus) - emit statusChanged(objectStatus); } } @@ -370,42 +394,54 @@ bool JsonDbNotify::parametersReady() return (completed && !queryString.isEmpty() && actionsList.count() && partitionObject); } -void JsonDbNotify::dbNotified(const QString ¬ify_uuid, const QtAddOn::JsonDb::JsonDbNotification &_notification) +void JsonDbNotify::onNotificationsAvailable() { - Q_UNUSED(notify_uuid); if (objectStatus != JsonDbNotify::Ready) { clearError(); objectStatus = JsonDbNotify::Ready; emit statusChanged(objectStatus); } - if (active) { - QJSValue obj = g_declEngine->toScriptValue(QVariant(_notification.object())); - emit notification(obj, (Actions)_notification.action(), _notification.stateNumber()); + if (active && watcher) { + QList<QJsonDbNotification> list = watcher->takeNotifications(); + for (int i = 0; i < list.count(); i++) { + const QJsonDbNotification & _notification = list[i]; + QJSValue obj = g_declEngine->toScriptValue(_notification.object().toVariantMap()); + emit notification(obj, (Actions)_notification.action(), _notification.stateNumber()); + } } } -void JsonDbNotify::dbNotifyReadyResponse(int id, const QVariant &result) +void JsonDbNotify::onStatusChanged(QtJsonDb::QJsonDbWatcher::Status newStatus) { - Q_UNUSED(id); - Q_UNUSED(result); + JsonDbNotify::Status oldStatus = objectStatus; + switch (newStatus) { + case QJsonDbWatcher::Inactive: + objectStatus = JsonDbNotify::Null; + break; + case QJsonDbWatcher::Activating: + objectStatus = JsonDbNotify::Registering; + break; + case QJsonDbWatcher::Active: + objectStatus = JsonDbNotify::Ready; + break; + } clearError(); - if (objectStatus != JsonDbNotify::Ready) { - objectStatus = JsonDbNotify::Ready; + if (oldStatus != objectStatus) { emit statusChanged(objectStatus); } } -void JsonDbNotify::dbNotifyErrorResponse(int id, int code, const QString &message) +void JsonDbNotify::onNotificationError(QtJsonDb::QJsonDbWatcher::ErrorCode code, const QString &message) { - Q_UNUSED(id); int oldErrorCode = errorCode; errorCode = code; errorString = message; - if (objectStatus != JsonDbNotify::Error) { + bool changed = (objectStatus != JsonDbNotify::Error); + if (changed) { objectStatus = JsonDbNotify::Error; emit statusChanged(objectStatus); } - if (oldErrorCode != errorCode) { + if (oldErrorCode != errorCode || changed) { emit errorChanged(error()); } } diff --git a/src/imports/jsondb/jsondbnotification.h b/src/imports/jsondb/jsondbnotification.h index 3957cd51..87af9928 100644 --- a/src/imports/jsondb/jsondbnotification.h +++ b/src/imports/jsondb/jsondbnotification.h @@ -48,7 +48,7 @@ #include <QJSValue> #include <QQmlParserStatus> #include <QQmlListProperty> -#include "jsondb-client.h" +#include <QJsonDbWatcher> QT_BEGIN_NAMESPACE_JSONDB @@ -102,10 +102,9 @@ Q_SIGNALS: private Q_SLOTS: void partitionNameChanged(const QString &partitionName); - void dbNotified(const QString ¬ify_uuid, const QtAddOn::JsonDb::JsonDbNotification &_notification); - void dbNotifyReadyResponse(int id, const QVariant &result); - void dbNotifyErrorResponse(int id, int code, const QString &message); - + void onNotificationsAvailable(); + void onStatusChanged(QtJsonDb::QJsonDbWatcher::Status newStatus); + void onNotificationError(QtJsonDb::QJsonDbWatcher::ErrorCode code, const QString &message); private: bool completed; QString queryString; @@ -118,6 +117,7 @@ private: QString errorString; Status objectStatus; bool active; + QPointer<QJsonDbWatcher> watcher; void init(); void clearError(); diff --git a/src/imports/jsondb/jsondbpartition.cpp b/src/imports/jsondb/jsondbpartition.cpp index 23023176..e88886ab 100644 --- a/src/imports/jsondb/jsondbpartition.cpp +++ b/src/imports/jsondb/jsondbpartition.cpp @@ -38,14 +38,14 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ - -#include "private/jsondb-strings_p.h" #include "jsondbpartition.h" +#include "jsondatabase.h" #include "jsondbnotification.h" #include "plugin.h" -#include "jsondb-client.h" #include "jsondbqueryobject.h" #include "jsondbchangessinceobject.h" +#include <QJsonDbCreateRequest> +#include <private/qjsondbstrings_p.h> #include <qdebug.h> QT_BEGIN_NAMESPACE_JSONDB @@ -67,12 +67,9 @@ JsonDbPartition::JsonDbPartition(const QString &partitionName, QObject *parent) :QObject(parent) ,_name(partitionName) { - connect(&jsonDb, SIGNAL(response(int,const QVariant&)), - this, SLOT(dbResponse(int,const QVariant&))); - connect(&jsonDb, SIGNAL(error(int,int,QString)), - this, SLOT(dbErrorResponse(int,int,QString))); } + JsonDbPartition::~JsonDbPartition() { } @@ -91,10 +88,10 @@ void JsonDbPartition::setName(const QString &partitionName) { if (partitionName != _name) { _name = partitionName; - foreach (QPointer<JsonDbNotify> notify, notifications) { - removeNotification(notify); + foreach (QPointer<QJsonDbWatcher> watcher, watchers) { + JsonDatabase::sharedConnection().removeWatcher(watcher); } - notifications.clear(); + watchers.clear(); // tell notifications to resubscribe emit nameChanged(partitionName); } @@ -112,6 +109,27 @@ static QVariant qjsvalue_to_qvariant(const QJSValue &value) } } } + +QList<QJsonObject> qvariantlist_to_qjsonobject_list(const QVariantList &list) +{ + QList<QJsonObject> objects; + int count = list.count(); + for (int i = 0; i < count; i++) { + objects.append(QJsonObject::fromVariantMap(list[i].toMap())); + } + return objects; +} + +QVariantList qjsonobject_list_to_qvariantlist(const QList<QJsonObject> &list) +{ + QVariantList objects; + int count = list.count(); + for (int i = 0; i < count; i++) { + objects.append(list[i].toVariantMap()); + } + return objects; +} + /*! \qmlmethod int QtJsonDb::Partition::create(object newObject, object options, function callback) @@ -168,9 +186,23 @@ int JsonDbPartition::create(const QJSValue &object, const QJSValue &options, co actualOptions = QJSValue(QJSValue::UndefinedValue); } //#TODO ADD options - int id = jsonDb.create(qjsvalue_to_qvariant(object), _name); - createCallbacks.insert(id, actualCallback); - return id; + QVariant obj = qjsvalue_to_qvariant(object); + QJsonDbWriteRequest *request(0); + if (obj.type() == QVariant::List) { + request = new QJsonDbCreateRequest(qvariantlist_to_qjsonobject_list(obj.toList())); + } else { + request = new QJsonDbCreateRequest(QJsonObject::fromVariantMap(obj.toMap())); + } + request->setPartition(_name); + connect(request, SIGNAL(finished()), this, SLOT(requestFinished())); + connect(request, SIGNAL(finished()), request, SLOT(deleteLater())); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SLOT(requestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + request, SLOT(deleteLater())); + JsonDatabase::sharedConnection().send(request); + writeCallbacks.insert(request, actualCallback); + return request->property("requestId").toInt(); } /*! @@ -241,9 +273,23 @@ int JsonDbPartition::update(const QJSValue &object, const QJSValue &options, co actualOptions = QJSValue(QJSValue::UndefinedValue); } //#TODO ADD options - int id = jsonDb.update(qjsvalue_to_qvariant(object), _name); - updateCallbacks.insert(id, actualCallback); - return id; + QVariant obj = qjsvalue_to_qvariant(object); + QJsonDbWriteRequest *request(0); + if (obj.type() == QVariant::List) { + request = new QJsonDbUpdateRequest(qvariantlist_to_qjsonobject_list(obj.toList())); + } else { + request = new QJsonDbUpdateRequest(QJsonObject::fromVariantMap(obj.toMap())); + } + request->setPartition(_name); + connect(request, SIGNAL(finished()), this, SLOT(requestFinished())); + connect(request, SIGNAL(finished()), request, SLOT(deleteLater())); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SLOT(requestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + request, SLOT(deleteLater())); + JsonDatabase::sharedConnection().send(request); + writeCallbacks.insert(request, actualCallback); + return request->property("requestId").toInt(); } /*! @@ -306,9 +352,23 @@ int JsonDbPartition::remove(const QJSValue &object, const QJSValue &options, co actualOptions = QJSValue(QJSValue::UndefinedValue); } //#TODO ADD options - int id = jsonDb.remove(qjsvalue_to_qvariant(object), _name); - removeCallbacks.insert(id, actualCallback); - return id; + QVariant obj = qjsvalue_to_qvariant(object); + QJsonDbWriteRequest *request(0); + if (obj.type() == QVariant::List) { + request = new QJsonDbRemoveRequest(qvariantlist_to_qjsonobject_list(obj.toList())); + } else { + request = new QJsonDbRemoveRequest(QJsonObject::fromVariantMap(obj.toMap())); + } + request->setPartition(_name); + connect(request, SIGNAL(finished()), this, SLOT(requestFinished())); + connect(request, SIGNAL(finished()), request, SLOT(deleteLater())); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SLOT(requestError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + request, SLOT(deleteLater())); + JsonDatabase::sharedConnection().send(request); + writeCallbacks.insert(request, actualCallback); + return request->property("requestId").toInt(); } /*! @@ -503,65 +563,47 @@ QQmlListProperty<QObject> JsonDbPartition::childElements() void JsonDbPartition::updateNotification(JsonDbNotify *notify) { - JsonDbClient::NotifyTypes notifyActions = JsonDbClient::NotifyCreate - | JsonDbClient::NotifyUpdate| JsonDbClient::NotifyRemove; - notify->uuid= jsonDb.registerNotification(notifyActions, notify->query(), _name - , notify, SLOT(dbNotified(QString,QtAddOn::JsonDb::JsonDbNotification)) - , notify, SLOT(dbNotifyReadyResponse(int,QVariant)) - , SLOT(dbNotifyErrorResponse(int,int,QString))); - notifications.insert(notify->uuid, notify); + JsonDatabase::sharedConnection().addWatcher(notify->watcher); + watchers.append(notify->watcher); } - void JsonDbPartition::removeNotification(JsonDbNotify *notify) { - if (notifications.contains(notify->uuid)) { - jsonDb.unregisterNotification(notify->uuid); - notifications.remove(notify->uuid); + if (watchers.contains(notify->watcher)) { + JsonDatabase::sharedConnection().removeWatcher(notify->watcher); + watchers.removeAll(notify->watcher); } } -void JsonDbPartition::call(QMap<int, QJSValue> &callbacks, int id, const QVariant &result) +void JsonDbPartition::call(QMap<QJsonDbWriteRequest*, QJSValue> &callbacks, QJsonDbWriteRequest *request) { - // Make sure that id exists in the map. - QJSValue callback = callbacks[id]; + QJSValue callback = callbacks[request]; QJSEngine *engine = callback.engine(); if (!engine) { - callbacks.remove(id); + callbacks.remove(request); return; } + QList<QJsonObject> objects = request->takeResults(); QJSValueList args; - QVariantMap object = result.toMap(); // object : id , statenumber , items QJSValue response= engine->newObject(); - response.setProperty(JsonDbString::kStateNumberStr, object.value(JsonDbString::kStateNumberStr).toInt()); - response.setProperty(JsonDbString::kIdStr, id); + response.setProperty(JsonDbStrings::Protocol::stateNumber(), request->stateNumber()); + response.setProperty(JsonDbStrings::Protocol::requestId(), request->property("requestId").toInt()); + QJSValue items = engine->toScriptValue(qjsonobject_list_to_qvariantlist(objects)); + response.setProperty(QLatin1String("items"), items); - // response object : object { _version & _uuid } (can be a list) - if (object.contains(QLatin1String("data"))) { - QJSValue items = engine->toScriptValue(object.value(QLatin1String("data"))); - response.setProperty(QLatin1String("items"), items); - } else { - // Create an array with a single element - QJSValue responseObject = engine->newObject(); - responseObject.setProperty(JsonDbString::kUuidStr, object.value(JsonDbString::kUuidStr).toString()); - responseObject.setProperty(JsonDbString::kVersionStr, object.value(JsonDbString::kVersionStr).toString()); - QJSValue items = engine->newArray(1); - items.setProperty(0, responseObject); - response.setProperty(QLatin1String("items"), items); - } args << QJSValue(QJSValue::UndefinedValue) << response; callback.call(args); - callbacks.remove(id); + callbacks.remove(request); } -void JsonDbPartition::callErrorCallback(QMap<int, QJSValue> &callbacks, int id, int code, const QString &message) +void JsonDbPartition::callErrorCallback(QMap<QJsonDbWriteRequest*, QJSValue> &callbacks, QJsonDbWriteRequest *request, + QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message) { - // Make sure that id exists in the map. - QJSValue callback = callbacks[id]; + QJSValue callback = callbacks[request]; QJSEngine *engine = callback.engine(); if (!engine) { - callbacks.remove(id); + callbacks.remove(request); return; } QJSValueList args; @@ -571,36 +613,13 @@ void JsonDbPartition::callErrorCallback(QMap<int, QJSValue> &callbacks, int id, // object : id QJSValue response = engine->newObject(); - response.setProperty(JsonDbString::kStateNumberStr, -1); - response.setProperty(JsonDbString::kIdStr, id); + response.setProperty(JsonDbStrings::Protocol::stateNumber(), -1); + response.setProperty(JsonDbStrings::Protocol::requestId(), request->property("requestId").toInt()); response.setProperty(QLatin1String("items"), engine->newArray()); args << engine->toScriptValue(QVariant(error))<< response; callback.call(args); - callbacks.remove(id); -} - - -void JsonDbPartition::dbResponse(int id, const QVariant &result) -{ - if (createCallbacks.contains(id)) { - call(createCallbacks, id, result); - } else if (updateCallbacks.contains(id)) { - call(updateCallbacks, id, result); - } else if (removeCallbacks.contains(id)) { - call(removeCallbacks, id, result); - } -} - -void JsonDbPartition::dbErrorResponse(int id, int code, const QString &message) -{ - if (createCallbacks.contains(id)) { - callErrorCallback(createCallbacks, id, code, message); - } else if (removeCallbacks.contains(id)) { - callErrorCallback(removeCallbacks, id, code, message); - } else if (updateCallbacks.contains(id)) { - callErrorCallback(updateCallbacks, id, code, message); - } + callbacks.remove(request); } void JsonDbPartition::queryFinished() @@ -614,8 +633,8 @@ void JsonDbPartition::queryFinished() QJSValueList args; // object : id , statenumber , items QJSValue response= engine->newObject(); - response.setProperty(JsonDbString::kStateNumberStr, object->stateNumber()); - response.setProperty(JsonDbString::kIdStr, id); + response.setProperty(JsonDbStrings::Protocol::stateNumber(), object->stateNumber()); + response.setProperty(JsonDbStrings::Protocol::requestId(), id); response.setProperty(QLatin1String("items"), engine->toScriptValue(object->takeResults())); args << QJSValue(QJSValue::UndefinedValue) << response; callback.call(args); @@ -637,8 +656,8 @@ void JsonDbPartition::queryStatusChanged() QJSValueList args; QJSValue response = engine->newObject(); - response.setProperty(JsonDbString::kStateNumberStr, -1); - response.setProperty(JsonDbString::kIdStr, id); + response.setProperty(JsonDbStrings::Protocol::stateNumber(), -1); + response.setProperty(JsonDbStrings::Protocol::requestId(), id); response.setProperty(QLatin1String("items"), engine->newArray()); args << engine->toScriptValue(object->error())<< response; @@ -650,6 +669,22 @@ void JsonDbPartition::queryStatusChanged() } } +void JsonDbPartition::requestFinished() +{ + QJsonDbWriteRequest *request = qobject_cast<QJsonDbWriteRequest *>(sender()); + if (writeCallbacks.contains(request)) { + call(writeCallbacks, request); + } +} + +void JsonDbPartition::requestError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message) +{ + QJsonDbWriteRequest *request = qobject_cast<QJsonDbWriteRequest *>(sender()); + if (writeCallbacks.contains(request)) { + callErrorCallback(writeCallbacks, request, code, message); + } + +} #include "moc_jsondbpartition.cpp" QT_END_NAMESPACE_JSONDB diff --git a/src/imports/jsondb/jsondbpartition.h b/src/imports/jsondb/jsondbpartition.h index 1c831c23..b8957a0f 100644 --- a/src/imports/jsondb/jsondbpartition.h +++ b/src/imports/jsondb/jsondbpartition.h @@ -49,8 +49,8 @@ #include <QJSValue> #include <QJSEngine> #include <QQmlListProperty> - -#include "jsondb-client.h" +#include <QJsonDbConnection> +#include <QJsonDbWriteRequest> QT_BEGIN_NAMESPACE_JSONDB @@ -105,27 +105,25 @@ private: QString _name; QString _file; QString _uuid; - JsonDbClient jsonDb; - QMap<int, QJSValue> createCallbacks; - QMap<int, QJSValue> updateCallbacks; - QMap<int, QJSValue> removeCallbacks; - QMap<QString, QPointer<JsonDbNotify> > notifications; + QList<QPointer<QJsonDbWatcher> > watchers; QList<QObject*> childQMLElements; QMap<JsonDbQueryObject*, QJSValue> findCallbacks; QMap<JsonDbQueryObject*, int> findIds; + QMap<QJsonDbWriteRequest*, QJSValue> writeCallbacks; void updateNotification(JsonDbNotify *notify); void removeNotification(JsonDbNotify *notify); - void call(QMap<int, QJSValue> &callbacks, int id, const QVariant &result); - void callErrorCallback(QMap<int, QJSValue> &callbacks, int id, int code, const QString &message); + void call(QMap<QJsonDbWriteRequest*, QJSValue> &callbacks, QJsonDbWriteRequest *request); + void callErrorCallback(QMap<QJsonDbWriteRequest*, QJSValue> &callbacks, QJsonDbWriteRequest *request, + QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message); private Q_SLOTS: - void dbResponse(int id, const QVariant &result); - void dbErrorResponse(int id, int code, const QString &message); void queryFinished(); void queryStatusChanged(); + void requestFinished(); + void requestError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message); friend class JsonDatabase; friend class JsonDbNotify; diff --git a/src/imports/jsondb/jsondbqueryobject.cpp b/src/imports/jsondb/jsondbqueryobject.cpp index b42daaa1..ac00e69c 100644 --- a/src/imports/jsondb/jsondbqueryobject.cpp +++ b/src/imports/jsondb/jsondbqueryobject.cpp @@ -38,10 +38,11 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "jsondb-global.h" #include "jsondbqueryobject.h" #include "jsondbpartition.h" -#include "private/jsondb-strings_p.h" +#include "jsondatabase.h" +#include <private/qjsondbstrings_p.h> +#include <jsondbmodelutils.h> #include <qdebug.h> QT_BEGIN_NAMESPACE_JSONDB @@ -84,7 +85,6 @@ JsonDbQueryObject::JsonDbQueryObject(QObject *parent) , queryLimit(-1) , partitionObject(0) , defaultPartitionObject(0) - , jsondbQuery(0) , errorCode(0) , objectStatus(JsonDbQueryObject::Null) { @@ -94,8 +94,8 @@ JsonDbQueryObject::~JsonDbQueryObject() { if (defaultPartitionObject) delete defaultPartitionObject; - if (jsondbQuery) - delete jsondbQuery; + if (readRequest) + delete readRequest; } @@ -145,8 +145,8 @@ void JsonDbQueryObject::setPartition(JsonDbPartition *newPartition) */ quint32 JsonDbQueryObject::stateNumber() const { - if (jsondbQuery) - return jsondbQuery->stateNumber(); + if (readRequest) + return readRequest->stateNumber(); return 0; } @@ -240,8 +240,8 @@ void JsonDbQueryObject::setBindings(const QVariantMap &newBindings) QVariantList JsonDbQueryObject::takeResults() { QVariantList list; - if (jsondbQuery) { - list = jsondbQuery->takeResults(); + if (readRequest) { + list = qjsonobject_list_to_qvariantlist(readRequest->takeResults()); } return list; } @@ -329,32 +329,29 @@ int JsonDbQueryObject::start() return -1; } - if (jsondbQuery) { - delete jsondbQuery; + if (readRequest) { + delete readRequest; } - jsondbQuery = partitionObject->jsonDb.query(); - jsondbQuery->setQuery(queryString); - jsondbQuery->setQueryLimit(queryLimit); - jsondbQuery->setQueryOffset(0); - jsondbQuery->setPartition(partitionObject->name()); + QJsonDbReadRequest *request = new QJsonDbReadRequest; + request->setQuery(queryString); + request->setQueryLimit(queryLimit); + request->setPartition(partitionObject->name()); QVariantMap::ConstIterator i = queryBindings.constBegin(); while (i != queryBindings.constEnd()) { - jsondbQuery->bindValue(i.key(), i.value()); + request->bindValue(i.key(), QJsonValue::fromVariant(i.value())); ++i; } - connect(jsondbQuery, SIGNAL(resultsReady(int)), - this, SIGNAL(resultsReady(int))); - connect(jsondbQuery, SIGNAL(finished()), - this, SLOT(setReadyStatus())); - connect(jsondbQuery, SIGNAL(finished()), - this, SIGNAL(finished())); - connect(jsondbQuery, SIGNAL(error(QtAddOn::JsonDb::JsonDbError::ErrorCode,QString)), - this, SLOT(setError(QtAddOn::JsonDb::JsonDbError::ErrorCode,QString))); - - jsondbQuery->start(); + connect(request, SIGNAL(resultsAvailable(int)), this, SIGNAL(resultsReady(int))); + connect(request, SIGNAL(finished()), this, SLOT(setReadyStatus())); + connect(request, SIGNAL(finished()), this, SIGNAL(finished())); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SLOT(setError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + objectStatus = JsonDbQueryObject::Loading; emit statusChanged(objectStatus); - return jsondbQuery->requestId(); + JsonDatabase::sharedConnection().send(request); + readRequest = request; + return request->property("requestId").toInt(); } @@ -405,16 +402,17 @@ void JsonDbQueryObject::setReadyStatus() emit statusChanged(objectStatus); } -void JsonDbQueryObject::setError(QtAddOn::JsonDb::JsonDbError::ErrorCode code, const QString& message) +void JsonDbQueryObject::setError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString & message) { int oldErrorCode = errorCode; errorCode = code; errorString = message; - if (objectStatus != JsonDbQueryObject::Error) { + bool changed = (objectStatus != JsonDbQueryObject::Error); + if (changed) { objectStatus = JsonDbQueryObject::Error; emit statusChanged(objectStatus); } - if (oldErrorCode != errorCode) { + if (oldErrorCode != errorCode || changed) { emit errorChanged(error()); } } diff --git a/src/imports/jsondb/jsondbqueryobject.h b/src/imports/jsondb/jsondbqueryobject.h index d629d26b..d7845c55 100644 --- a/src/imports/jsondb/jsondbqueryobject.h +++ b/src/imports/jsondb/jsondbqueryobject.h @@ -48,7 +48,7 @@ #include <QJSValue> #include <QQmlParserStatus> #include <QQmlListProperty> -#include "jsondb-client.h" +#include <QJsonDbReadRequest> QT_BEGIN_NAMESPACE_JSONDB @@ -106,7 +106,7 @@ Q_SIGNALS: void errorChanged(const QVariantMap &newError); private Q_SLOTS: - void setError(QtAddOn::JsonDb::JsonDbError::ErrorCode code, const QString& message); + void setError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString & message); void setReadyStatus(); private: @@ -116,11 +116,11 @@ private: QVariantList results; QPointer<JsonDbPartition> partitionObject; QPointer<JsonDbPartition> defaultPartitionObject; - QPointer<JsonDbQuery> jsondbQuery; int errorCode; QString errorString; Status objectStatus; QVariantMap queryBindings; + QPointer<QJsonDbReadRequest> readRequest; void clearError(); inline bool parametersReady(); diff --git a/src/imports/jsondb/jsondbsortinglistmodel.cpp b/src/imports/jsondb/jsondbsortinglistmodel.cpp index c70b19ed..8bb84c3a 100644 --- a/src/imports/jsondb/jsondbsortinglistmodel.cpp +++ b/src/imports/jsondb/jsondbsortinglistmodel.cpp @@ -41,12 +41,9 @@ #include "jsondbsortinglistmodel.h" #include "jsondbsortinglistmodel_p.h" -#include "private/jsondb-strings_p.h" #include "plugin.h" - -#include <QJSEngine> -#include <QJSValueIterator> - +#include "jsondatabase.h" +#include <qdebug.h> /*! \internal \class JsonDbSortingListModel @@ -62,16 +59,12 @@ JsonDbSortingListModelPrivate::JsonDbSortingListModelPrivate(JsonDbSortingListMo , limit(-1) , chunkSize(100) , state(JsonDbSortingListModel::None) + , errorCode(0) { } void JsonDbSortingListModelPrivate::init() { - Q_Q(JsonDbSortingListModel); - q->connect(&dbClient, SIGNAL(response(int,const QVariant&)), - q, SLOT(_q_jsonDbResponse(int,const QVariant&))); - q->connect(&dbClient, SIGNAL(error(int,int,const QString&)), - q, SLOT(_q_jsonDbErrorResponse(int,int,const QString&))); } JsonDbSortingListModelPrivate::~JsonDbSortingListModelPrivate() @@ -218,13 +211,9 @@ void JsonDbSortingListModelPrivate::updateItem(const QVariantMap &item, int part } } -void JsonDbSortingListModelPrivate::fillData(const QVariant &v, int partitionIndex) +void JsonDbSortingListModelPrivate::fillData(const QVariantList &items, int partitionIndex) { Q_Q(JsonDbSortingListModel); - QVariantMap m = v.toMap(); - QVariantList items; - if (m.contains(QLatin1String("data"))) - items = m.value(QLatin1String("data")).toList(); RequestInfo &r = partitionObjectDetails[partitionIndex]; r.lastSize = items.size(); if (resetModel) { @@ -280,7 +269,7 @@ void JsonDbSortingListModelPrivate::fillData(const QVariant &v, int partitionInd emit q->stateChanged(state); for (int i = 0; i<pendingNotifications.size(); i++) { const NotifyItem &pending = pendingNotifications[i]; - sendNotifications(pending.notifyUuid, pendingNotifications[i].item, pendingNotifications[i].action); + sendNotifications(pending.partitionIndex, pending.item, pending.action); } pendingNotifications.clear(); // overflow status is used when handling notifications. @@ -290,7 +279,7 @@ void JsonDbSortingListModelPrivate::fillData(const QVariant &v, int partitionInd overflow = false; } else if (r.lastSize >= chunkSize){ // more items, fetch next chunk - fetchNextChunk(partitionIndex); + fetchPartition(partitionIndex, false); } } @@ -333,7 +322,7 @@ void JsonDbSortingListModelPrivate::reset() emit q->stateChanged(state); } -void JsonDbSortingListModelPrivate::fetchPartition(int index) +void JsonDbSortingListModelPrivate::fetchPartition(int index, bool reset) { Q_Q(JsonDbSortingListModel); if (index >= partitionObjects.count()) @@ -345,11 +334,19 @@ void JsonDbSortingListModelPrivate::fetchPartition(int index) } RequestInfo &r = partitionObjectDetails[index]; QPointer<JsonDbPartition> p = partitionObjects[index]; - if (p) { + Q_ASSERT(p); + if (reset) { r.lastSize = -1; r.lastOffset = 0; - r.requestId = dbClient.query(query, r.lastOffset, chunkSize, p->name()); + } else { + r.lastOffset += chunkSize; } + QJsonDbReadRequest *request = valueRequests[index]->newRequest(index); + request->setQuery(query); + request->setProperty("queryOffset", r.lastOffset); + request->setQueryLimit(chunkSize); + request->setPartition(p->name()); + JsonDatabase::sharedConnection().send(request); } void JsonDbSortingListModelPrivate::fetchModel(bool reset) @@ -365,21 +362,14 @@ void JsonDbSortingListModelPrivate::fetchModel(bool reset) } } -void JsonDbSortingListModelPrivate::fetchNextChunk(int partitionIndex) -{ - RequestInfo &r = partitionObjectDetails[partitionIndex]; - r.lastOffset += chunkSize; - r.requestId = dbClient.query(query, r.lastOffset, chunkSize, partitionObjects[partitionIndex]->name()); -} - void JsonDbSortingListModelPrivate::clearNotification(int index) { if (index >= partitionObjects.count()) return; RequestInfo &r = partitionObjectDetails[index]; - if (!r.notifyUuid.isEmpty()) { - dbClient.unregisterNotification(r.notifyUuid); + if (r.watcher) { + JsonDatabase::sharedConnection().removeWatcher(r.watcher); } r.clear(); } @@ -396,14 +386,16 @@ void JsonDbSortingListModelPrivate::createOrUpdateNotification(int index) if (index >= partitionObjects.count()) return; clearNotification(index); - JsonDbClient::NotifyTypes notifyActions = JsonDbClient::NotifyCreate - | JsonDbClient::NotifyUpdate| JsonDbClient::NotifyRemove; - partitionObjectDetails[index].notifyUuid= dbClient.registerNotification( - notifyActions , query, partitionObjects[index]->name(), - q, SLOT(_q_dbNotified(QString,QtAddOn::JsonDb::JsonDbNotification)), - q, SLOT(_q_dbNotifyReadyResponse(int,QVariant)), - SLOT(_q_dbNotifyErrorResponse(int,int,QString))); - + QJsonDbWatcher *watcher = new QJsonDbWatcher(); + watcher->setQuery(query); + watcher->setWatchedActions(QJsonDbWatcher::Created | QJsonDbWatcher::Updated |QJsonDbWatcher::Removed); + watcher->setPartition(partitionObjects[index]->name()); + QObject::connect(watcher, SIGNAL(notificationsAvailable(int)), + q, SLOT(_q_notificationsAvailable())); + QObject::connect(watcher, SIGNAL(error(QtJsonDb::QJsonDbWatcher::ErrorCode,QString)), + q, SLOT(_q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode,QString))); + JsonDatabase::sharedConnection().addWatcher(watcher); + partitionObjectDetails[index].watcher = watcher; } void JsonDbSortingListModelPrivate::createOrUpdateNotifications() @@ -433,19 +425,10 @@ void JsonDbSortingListModelPrivate::parseSortOrder() } } -int JsonDbSortingListModelPrivate::indexOfrequestId(int requestId) -{ - for (int i = 0; i<partitionObjectDetails.count(); i++) { - if (requestId == partitionObjectDetails[i].requestId) - return i; - } - return -1; -} - -int JsonDbSortingListModelPrivate::indexOfNotifyUUID(const QString& notifyUuid) +int JsonDbSortingListModelPrivate::indexOfWatcher(QJsonDbWatcher *watcher) { - for (int i = 0; i<partitionObjectDetails.count(); i++) { - if (notifyUuid == partitionObjectDetails[i].notifyUuid) + for (int i = 0; i < partitionObjectDetails.count(); i++) { + if (watcher == partitionObjectDetails[i].watcher) return i; } return -1; @@ -489,38 +472,31 @@ int JsonDbSortingListModelPrivate::indexOf(const QString &uuid) const return iterator_position(begin, end, i); } -void JsonDbSortingListModelPrivate::sendNotifications(const QString& currentNotifyUuid, const QVariant &v, JsonDbClient::NotifyType action) +void JsonDbSortingListModelPrivate::sendNotifications(int partitionIndex, const QVariantMap &v, QJsonDbWatcher::Action action) { - int idx = indexOfNotifyUUID(currentNotifyUuid); - if (idx == -1) - return; - - const QVariantMap &item = v.toMap(); - if (action == JsonDbClient::NotifyCreate) { - addItem(item, idx); - } else if (action == JsonDbClient::NotifyRemove) { - deleteItem(item, idx); - } else if (action == JsonDbClient::NotifyUpdate) { - updateItem(item, idx); + if (action == QJsonDbWatcher::Created) { + addItem(v, partitionIndex); + } else if (action == QJsonDbWatcher::Removed) { + deleteItem(v, partitionIndex); + } else if (action == QJsonDbWatcher::Updated) { + updateItem(v, partitionIndex); } } -void JsonDbSortingListModelPrivate::_q_jsonDbResponse(int id, const QVariant &v) +void JsonDbSortingListModelPrivate::_q_valueResponse(int index, const QList<QJsonObject> &v) { - int idx = indexOfrequestId(id); - if (idx != -1) { - partitionObjectDetails[idx].requestId = -1; - fillData(v, idx); - } + fillData(qjsonobject_list_to_qvariantlist(v), index); } -void JsonDbSortingListModelPrivate::_q_jsonDbErrorResponse(int id, int code, const QString &message) +void JsonDbSortingListModelPrivate::_q_readError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString & message) { - int idx = -1; - if ((idx = indexOfrequestId(id)) != -1) { - partitionObjectDetails[idx].requestId = -1; - qWarning() << QString("JsonDb error: %1 %2").arg(code).arg(message); - } + Q_Q(JsonDbSortingListModel); + qWarning() << QString("JsonDb error: %1 %2").arg(code).arg(message); + int oldErrorCode = errorCode; + errorCode = code; + errorString = message; + if (oldErrorCode != errorCode) + emit q->errorChanged(q->error()); } void JsonDbSortingListModelPrivate::_q_refreshModel() @@ -529,27 +505,58 @@ void JsonDbSortingListModelPrivate::_q_refreshModel() fetchModel(false); } -void JsonDbSortingListModelPrivate::_q_dbNotified(const QString ¬ify_uuid, const QtAddOn::JsonDb::JsonDbNotification &_notification) +void JsonDbSortingListModelPrivate::_q_notificationsAvailable() { - if (state == JsonDbSortingListModel::Querying) { - NotifyItem pending; - pending.notifyUuid = notify_uuid; - pending.item = _notification.object(); - pending.action = _notification.action(); - pendingNotifications.append(pending); - } else if (state == JsonDbSortingListModel::Ready) { - sendNotifications(notify_uuid, _notification.object(), _notification.action()); + Q_Q(JsonDbSortingListModel); + QJsonDbWatcher *watcher = qobject_cast<QJsonDbWatcher *>(q->sender()); + int partitionIndex = indexOfWatcher(watcher); + if (!watcher || partitionIndex == -1) + return; + QList<QJsonDbNotification> list = watcher->takeNotifications(); + for (int i = 0; i < list.count(); i++) { + const QJsonDbNotification & notification = list[i]; + QVariantMap object = notification.object().toVariantMap(); + if (state == JsonDbSortingListModel::Querying) { + NotifyItem pending; + pending.partitionIndex = partitionIndex; + pending.item = object; + pending.action = notification.action(); + pendingNotifications.append(pending); + } else if (state == JsonDbSortingListModel::Ready) { + sendNotifications(partitionIndex, object, notification.action()); + } } } -void JsonDbSortingListModelPrivate::_q_dbNotifyReadyResponse(int /* id */, const QVariant &/* result */) +void JsonDbSortingListModelPrivate::_q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode code, const QString &message) { + Q_Q(JsonDbSortingListModel); + qWarning() << QString("JsonDbSortingListModel Notification error: %1 %2").arg(code).arg(message); + int oldErrorCode = errorCode; + errorCode = code; + errorString = message; + if (oldErrorCode != errorCode) + emit q->errorChanged(q->error()); } -void JsonDbSortingListModelPrivate::_q_dbNotifyErrorResponse(int id, int code, const QString &message) +void JsonDbSortingListModelPrivate::appendPartition(JsonDbPartition *v) { - Q_UNUSED(id); - qWarning() << QString("JsonDbSortingListModel Notification error: %1 %2").arg(code).arg(message); + Q_Q(JsonDbSortingListModel); + partitionObjects.append(QPointer<JsonDbPartition>(v)); + partitionObjectDetails.append(RequestInfo()); + ModelRequest *valueRequest = new ModelRequest(); + QObject::connect(valueRequest, SIGNAL(finished(int,QList<QJsonObject>,QString)), + q, SLOT(_q_valueResponse(int,QList<QJsonObject>))); + QObject::connect(valueRequest, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + q, SLOT(_q_readError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + valueRequests.append(valueRequest); + if (componentComplete && !query.isEmpty()) { + createOrUpdateNotification(partitionObjects.count()-1); + if (state == JsonDbSortingListModel::None) { + resetModel = true; + } + fetchPartition(partitionObjects.count()-1); + } } void JsonDbSortingListModelPrivate::partitions_append(QQmlListProperty<JsonDbPartition> *p, JsonDbPartition *v) @@ -557,15 +564,7 @@ void JsonDbSortingListModelPrivate::partitions_append(QQmlListProperty<JsonDbPar JsonDbSortingListModel *q = qobject_cast<JsonDbSortingListModel *>(p->object); JsonDbSortingListModelPrivate *pThis = (q) ? q->d_func() : 0; if (pThis) { - pThis->partitionObjects.append(QPointer<JsonDbPartition>(v));\ - pThis->partitionObjectDetails.append(RequestInfo()); - if (pThis->componentComplete && !pThis->query.isEmpty()) { - pThis->createOrUpdateNotification(pThis->partitionObjects.count()-1); - if (pThis->state == JsonDbSortingListModel::None) { - pThis->resetModel = true; - } - pThis->fetchPartition(pThis->partitionObjects.count()-1); - } + pThis->appendPartition(v); } } @@ -589,14 +588,23 @@ JsonDbPartition* JsonDbSortingListModelPrivate::partitions_at(QQmlListProperty<J return 0; } +void JsonDbSortingListModelPrivate::clearPartitions() +{ + partitionObjects.clear(); + partitionObjectDetails.clear(); + while (!valueRequests.isEmpty()) { + delete valueRequests[0]; + valueRequests.removeFirst(); + } + reset(); +} + void JsonDbSortingListModelPrivate::partitions_clear(QQmlListProperty<JsonDbPartition> *p) { JsonDbSortingListModel *q = qobject_cast<JsonDbSortingListModel *>(p->object); JsonDbSortingListModelPrivate *pThis = (q) ? q->d_func() : 0; if (pThis) { - pThis->partitionObjects.clear(); - pThis->partitionObjectDetails.clear(); - pThis->reset(); + pThis->clearPartitions(); } } @@ -859,6 +867,7 @@ void JsonDbSortingListModel::setQueryLimit(int newQueryLimit) /*! \qmlproperty bool QtJsonDb::JsonDbSortingListModel::overflow + \readonly This will be true if actual numer of results is more than the queryLimit */ @@ -954,6 +963,7 @@ void JsonDbSortingListModel::setSortOrder(const QString &newSortOrder) /*! \qmlproperty State QtJsonDb::JsonDbSortingListModel::state + \readonly The current state of the model. \list \li State.None - The model is not initialized @@ -1045,5 +1055,25 @@ JsonDbPartition* JsonDbSortingListModel::getPartition(int index) const This handler is called when the number of items in the model has changed. */ +/*! + \qmlproperty object QtJsonDb::JsonDbSortingListModel::error + \readonly + + This property holds the current error information for the object. It contains: + \list + \o error.code - code for the current error. + \o error.message - detailed explanation of the error + \endlist +*/ + +QVariantMap JsonDbSortingListModel::error() const +{ + Q_D(const JsonDbSortingListModel); + QVariantMap errorMap; + errorMap.insert(QLatin1String("code"), d->errorCode); + errorMap.insert(QLatin1String("message"), d->errorString); + return errorMap; +} + #include "moc_jsondbsortinglistmodel.cpp" QT_END_NAMESPACE_JSONDB diff --git a/src/imports/jsondb/jsondbsortinglistmodel.h b/src/imports/jsondb/jsondbsortinglistmodel.h index 99ef4058..cdd9f7a7 100644 --- a/src/imports/jsondb/jsondbsortinglistmodel.h +++ b/src/imports/jsondb/jsondbsortinglistmodel.h @@ -53,7 +53,6 @@ #include <QJSValue> #include <QScopedPointer> -#include "jsondb-global.h" #include "jsondbpartition.h" QT_BEGIN_NAMESPACE_JSONDB @@ -79,8 +78,8 @@ public: Q_PROPERTY(QVariant roleNames READ scriptableRoleNames WRITE setScriptableRoleNames) Q_PROPERTY(int queryLimit READ queryLimit WRITE setQueryLimit) Q_PROPERTY(bool overflow READ overflow) - Q_PROPERTY(QQmlListProperty<JsonDbPartition> partitions READ partitions) + Q_PROPERTY(QVariantMap error READ error NOTIFY errorChanged) virtual void classBegin(); virtual void componentComplete(); @@ -111,10 +110,12 @@ public: Q_INVOKABLE QJSValue get(int index) const; Q_INVOKABLE QVariant get(int index, const QString &property) const; Q_INVOKABLE JsonDbPartition* getPartition(int index) const; + QVariantMap error() const; signals: void stateChanged(State state) const; void rowCountChanged(int newCount) const; + void errorChanged(QVariantMap newError); private Q_SLOTS: void partitionNameChanged(const QString &partitionName); @@ -123,12 +124,12 @@ private: Q_DISABLE_COPY(JsonDbSortingListModel) Q_DECLARE_PRIVATE(JsonDbSortingListModel) QScopedPointer<JsonDbSortingListModelPrivate> d_ptr; - Q_PRIVATE_SLOT(d_func(), void _q_jsonDbResponse(int, const QVariant&)) - Q_PRIVATE_SLOT(d_func(), void _q_jsonDbErrorResponse(int, int, const QString&)) + Q_PRIVATE_SLOT(d_func(), void _q_refreshModel()) - Q_PRIVATE_SLOT(d_func(), void _q_dbNotified(QString, QtAddOn::JsonDb::JsonDbNotification)) - Q_PRIVATE_SLOT(d_func(), void _q_dbNotifyReadyResponse(int, QVariant)) - Q_PRIVATE_SLOT(d_func(), void _q_dbNotifyErrorResponse(int, int, QString)) + Q_PRIVATE_SLOT(d_func(), void _q_notificationsAvailable()) + Q_PRIVATE_SLOT(d_func(), void _q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode, QString)) + Q_PRIVATE_SLOT(d_func(), void _q_valueResponse(int, QList<QJsonObject>)) + Q_PRIVATE_SLOT(d_func(), void _q_readError(QtJsonDb::QJsonDbRequest::ErrorCode, QString)) }; diff --git a/src/imports/jsondb/jsondbsortinglistmodel_p.h b/src/imports/jsondb/jsondbsortinglistmodel_p.h index 0cd45d02..29837a78 100644 --- a/src/imports/jsondb/jsondbsortinglistmodel_p.h +++ b/src/imports/jsondb/jsondbsortinglistmodel_p.h @@ -49,9 +49,9 @@ #include <QStringList> #include <QPointer> #include <QUuid> +#include <QJSEngine> +#include <QJSValueIterator> -#include "jsondb-client.h" -#include "private/jsondb-connection_p.h" #include "jsondbmodelutils.h" QT_BEGIN_NAMESPACE_JSONDB @@ -88,10 +88,12 @@ public: QHash<int, QStringList> properties; QList<NotifyItem> pendingNotifications; + QList< QPointer<ModelRequest> >valueRequests; JsonDbSortingListModel::State state; - JsonDbClient dbClient; QModelIndex parent; + int errorCode; + QString errorString; public: JsonDbSortingListModelPrivate(JsonDbSortingListModel *q); @@ -102,13 +104,12 @@ public: void addItem(const QVariantMap &item, int partitionIndex); void deleteItem(const QVariantMap &item, int partitionIndex); void updateItem(const QVariantMap &item, int partitionIndex); - void fillData(const QVariant &v, int partitionIndex); + void fillData(const QVariantList &items, int partitionIndex); void sortObjects(); void reset(); - void fetchPartition(int index); + void fetchPartition(int index, bool reset = true); void fetchModel(bool reset = true); - void fetchNextChunk(int partitionIndex); void clearNotification(int index); void clearNotifications(); @@ -118,7 +119,10 @@ public: int indexOfrequestId(int requestId); int indexOfNotifyUUID(const QString& notifyUuid); + int indexOfWatcher(QJsonDbWatcher *watcher); + void appendPartition(JsonDbPartition *v); + void clearPartitions(); QVariant getItem(int index); QVariant getItem(int index, int role); JsonDbPartition* getItemPartition(int index); @@ -126,15 +130,14 @@ public: void set(int index, const QJSValue& valuemap, const QJSValue &successCallback, const QJSValue &errorCallback); - void sendNotifications(const QString&, const QVariant &, JsonDbClient::NotifyType); + void sendNotifications(int partitionIndex, const QVariantMap &v, QJsonDbWatcher::Action action); // private slots - void _q_jsonDbResponse(int , const QVariant &); - void _q_jsonDbErrorResponse(int , int, const QString&); void _q_refreshModel(); - void _q_dbNotified(const QString ¬ify_uuid, const QtAddOn::JsonDb::JsonDbNotification &_notification); - void _q_dbNotifyReadyResponse(int id, const QVariant &result); - void _q_dbNotifyErrorResponse(int id, int code, const QString &message); + void _q_notificationsAvailable(); + void _q_notificationError(QtJsonDb::QJsonDbWatcher::ErrorCode code, const QString &message); + void _q_readError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString & message); + void _q_valueResponse(int , const QList<QJsonObject>&); static void partitions_append(QQmlListProperty<JsonDbPartition> *p, JsonDbPartition *v); static int partitions_count(QQmlListProperty<JsonDbPartition> *p); diff --git a/src/imports/jsondb/plugin.cpp b/src/imports/jsondb/plugin.cpp index 7f1af61e..5afe4bb1 100644 --- a/src/imports/jsondb/plugin.cpp +++ b/src/imports/jsondb/plugin.cpp @@ -41,13 +41,13 @@ #include "plugin.h" -#include "jsondblistmodel.h" -#include "jsondbsortinglistmodel.h" #include "jsondatabase.h" #include "jsondbpartition.h" #include "jsondbnotification.h" #include "jsondbqueryobject.h" #include "jsondbchangessinceobject.h" +#include "jsondblistmodel.h" +#include "jsondbsortinglistmodel.h" #include "jsondbcachinglistmodel.h" QT_USE_NAMESPACE_JSONDB @@ -73,11 +73,11 @@ void JsonDbPlugin::registerTypes(const char *uri) { Q_ASSERT(uri == QLatin1String("QtJsonDb")); qmlRegisterModuleApi(uri, 1, 0, jsondb_new_module_api_provider); - qmlRegisterType<JsonDbListModel>(uri, 1, 0, "JsonDbListModel"); - qmlRegisterType<JsonDbSortingListModel>(uri, 1, 0, "JsonDbSortingListModel"); qmlRegisterType<JsonDbPartition>(uri, 1, 0, "Partition"); qmlRegisterType<JsonDbNotify>(uri, 1, 0, "Notification"); qmlRegisterType<JsonDbQueryObject>(uri, 1, 0, "Query"); qmlRegisterType<JsonDbChangesSinceObject>(uri, 1, 0, "ChangesSince"); + qmlRegisterType<JsonDbListModel>(uri, 1, 0, "JsonDbListModel"); + qmlRegisterType<JsonDbSortingListModel>(uri, 1, 0, "JsonDbSortingListModel"); qmlRegisterType<JsonDbCachingListModel>(uri, 1, 0, "JsonDbCachingListModel"); } diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 31d18ffc..16ddd0af 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -11,7 +11,7 @@ SUBDIRS = \ jsondbpartition \ jsondbnotification \ jsondbqueryobject \ - jsondbchangessinceobject \ +# jsondbchangessinceobject \ queries \ qjsondbrequest \ qjsondbwatcher \ diff --git a/tests/auto/jsondb-listmodel/test-jsondb-listmodel.cpp b/tests/auto/jsondb-listmodel/test-jsondb-listmodel.cpp index bdd1bb3a..41ce2711 100644 --- a/tests/auto/jsondb-listmodel/test-jsondb-listmodel.cpp +++ b/tests/auto/jsondb-listmodel/test-jsondb-listmodel.cpp @@ -215,12 +215,13 @@ void TestJsonDbListModel::createItem() waitForExitOrTimeout(); QCOMPARE(listModel->count(), 1); + mItemsCreated = 0; item.insert("_type", __FUNCTION__); item.insert("name", "Baker"); id = mClient->create(item); waitForResponse1(id); - - waitForExitOrTimeout();; + if (!mItemsCreated) + waitForExitOrTimeout();; QCOMPARE(listModel->count(), 2); deleteModel(listModel); } @@ -367,10 +368,12 @@ void TestJsonDbListModel::deleteItem() waitForExitOrTimeout(); QCOMPARE(listModel->rowCount(), 1); + mItemsCreated = 0; item.insert("name", "Baker"); id = mClient->create(item); waitForResponse1(id); - waitForExitOrTimeout(); + if (!mItemsCreated) + waitForExitOrTimeout();; QCOMPARE(listModel->rowCount(), 2); mWaitingForRowsRemoved = true; diff --git a/tests/auto/jsondbcachinglistmodel/jsondbcachinglistmodel.pro b/tests/auto/jsondbcachinglistmodel/jsondbcachinglistmodel.pro index 16c759cc..1762a90b 100644 --- a/tests/auto/jsondbcachinglistmodel/jsondbcachinglistmodel.pro +++ b/tests/auto/jsondbcachinglistmodel/jsondbcachinglistmodel.pro @@ -1,9 +1,9 @@ TEMPLATE = app TARGET = tst_jsondbcachinglistmodel DEPENDPATH += . -INCLUDEPATH += . +INCLUDEPATH += . ../../shared/ -QT = core network testlib gui qml jsondbcompat-private +QT = core network testlib gui qml jsondb CONFIG -= app_bundle CONFIG += testcase @@ -12,5 +12,6 @@ include($$PWD/../../shared/shared.pri) DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\" DEFINES += SRCDIR=\\\"$$PWD/\\\" -HEADERS += testjsondbcachinglistmodel.h +HEADERS += testjsondbcachinglistmodel.h \ + $$PWD/../../shared/requestwrapper.h SOURCES += testjsondbcachinglistmodel.cpp diff --git a/tests/auto/jsondbcachinglistmodel/testjsondbcachinglistmodel.cpp b/tests/auto/jsondbcachinglistmodel/testjsondbcachinglistmodel.cpp index 9ad9ee89..4eb02301 100644 --- a/tests/auto/jsondbcachinglistmodel/testjsondbcachinglistmodel.cpp +++ b/tests/auto/jsondbcachinglistmodel/testjsondbcachinglistmodel.cpp @@ -55,18 +55,8 @@ ModelData::~ModelData() { if (model) delete model; - if (partition1) - delete partition1; - if (partition2) - delete partition2; - if (component) delete component; - if (partitionComponent1) - delete partitionComponent1; - if (partitionComponent2) - delete partitionComponent2; - if (engine) delete engine; } @@ -74,12 +64,16 @@ ModelData::~ModelData() const QString qmlProgram = QLatin1String( "import QtQuick 2.0 \n" "import QtJsonDb 1.0 as JsonDb \n" - "signal callbackSignal(variant index, variant response)" - "function updateItemCallback(index, response) { callbackSignal( index, response); }"); - + "JsonDb.JsonDbCachingListModel {" + "signal callbackSignal(variant index, variant response);" + "id: contactsModel; cacheSize: 200;" + "partitions: [" + "JsonDb.Partition {name: \"com.nokia.shared.1\"}," + "JsonDb.Partition {name: \"com.nokia.shared.2\"}" + "]" + "}"); TestJsonDbCachingListModel::TestJsonDbCachingListModel() - : mWaitingForNotification(false), mWaitingForDataChange(false), mWaitingForRowsRemoved(false) { } @@ -96,7 +90,6 @@ void TestJsonDbCachingListModel::deleteDbFiles() nameFilter << "objectFile.bin" << "objectFile2.bin"; QFileInfoList databaseFiles = currentDir.entryInfoList(nameFilter, QDir::Files); foreach (QFileInfo fileInfo, databaseFiles) { - //qDebug() << "Deleted : " << fileInfo.fileName(); QFile file(fileInfo.fileName()); file.remove(); } @@ -122,29 +115,25 @@ void TestJsonDbCachingListModel::initTestCase() QString socketName = QString("testjsondb_%1").arg(getpid()); mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile); - mClient = new JsonDbClient(this); - connect(mClient, SIGNAL(notified(QString,QtAddOn::JsonDb::JsonDbNotification)), - this, SLOT(notified(QString,QtAddOn::JsonDb::JsonDbNotification))); - connect( mClient, SIGNAL(response(int, const QVariant&)), - this, SLOT(response(int, const QVariant&))); - connect( mClient, SIGNAL(error(int, int, const QString&)), - this, SLOT(error(int, int, const QString&))); + connection = new QJsonDbConnection(); + connection->connectToServer(); mPluginPath = findQMLPluginPath("QtJsonDb"); + if (mPluginPath.isEmpty()) + qDebug() << "Couldn't find the plugin path for the plugin QtJsonDb"; // Create the shared Partitions QVariantMap item; item.insert("_type", "Partition"); item.insert("name", "com.nokia.shared.1"); - int id = mClient->create(item); + int id = create(item); waitForResponse1(id); item.clear(); item.insert("_type", "Partition"); item.insert("name", "com.nokia.shared.2"); - id = mClient->create(item); + id = create(item); waitForResponse1(id); - } QAbstractListModel *TestJsonDbCachingListModel::createModel() @@ -158,37 +147,12 @@ QAbstractListModel *TestJsonDbCachingListModel::createModel() return 0; } newModel->component = new QQmlComponent(newModel->engine); - newModel->component->setData("import QtQuick 2.0\nimport QtJsonDb 1.0 as JsonDb \n" - "JsonDb.JsonDbCachingListModel {signal callbackSignal(variant index, variant response); id: contactsModel; cacheSize: 200;}", - QUrl()); + newModel->component->setData(qmlProgram.toLocal8Bit(), QUrl()); + newModel->model = newModel->component->create(); if (newModel->component->isError()) qDebug() << newModel->component->errors(); - QObject::connect(newModel->model, SIGNAL(callbackSignal(QVariant, QVariant)), - this, SLOT(callbackSlot(QVariant, QVariant))); - - newModel->partitionComponent1 = new QQmlComponent(newModel->engine); - newModel->partitionComponent1->setData("import QtQuick 2.0\nimport QtJsonDb 1.0 as JsonDb \n" - "JsonDb.Partition {name: \"com.nokia.shared.1\"}", - QUrl()); - newModel->partition1 = newModel->partitionComponent1->create(); - if (newModel->partitionComponent1->isError()) - qDebug() << newModel->partitionComponent1->errors(); - - - newModel->partitionComponent2 = new QQmlComponent(newModel->engine); - newModel->partitionComponent2->setData("import QtQuick 2.0\nimport QtJsonDb 1.0 as JsonDb \n" - "JsonDb.Partition {name: \"com.nokia.shared.2\"}", - QUrl()); - newModel->partition2 = newModel->partitionComponent2->create(); - if (newModel->partitionComponent2->isError()) - qDebug() << newModel->partitionComponent2->errors(); - - QQmlListReference partitions(newModel->model, "partitions", newModel->engine); - partitions.append(newModel->partition1); - partitions.append(newModel->partition2); - mModels.append(newModel); return (QAbstractListModel*)(newModel->model); } @@ -215,26 +179,16 @@ void TestJsonDbCachingListModel::cleanupTestCase() deleteDbFiles(); } -void TestJsonDbCachingListModel::callbackSlot(QVariant error, QVariant response) +QVariant TestJsonDbCachingListModel::getIndex(QAbstractListModel *model, int index, int role) { - mCallbackReceived = true; - callbackError = error.isValid(); - callbackMeta = response; - callbackResponse = response.toMap().value("object"); - mEventLoop.quit(); -} - -void TestJsonDbCachingListModel::getIndex(int index) -{ - mCallbackReceived = false; - - const QString createString = QString("get(%1, function (error, response) {callbackSignal(error, response);});"); - const QString getString = QString(createString).arg(index); - QQmlExpression expr(mModels.last()->engine->rootContext(), mModels.last()->model, getString); - expr.evaluate().toInt(); - - if (!mCallbackReceived) - waitForCallback(); + QVariant val = model->data(model->index(index), role); + while (val.isNull()) { + //qDebug() << "Cache miss, no worries"; + mWaitingForStateChanged = true; + waitForStateOrTimeout(); + val = model->data(model->index(index), role); + } + return val; } int indexOf(QObject* object, const QString &uuid) @@ -254,21 +208,21 @@ void TestJsonDbCachingListModel::createIndex(const QString &property, const QStr item.insert("propertyName", property); item.insert("propertyType", propertyType); - int id = mClient->create(item, "com.nokia.shared.1"); + int id = create(item, "com.nokia.shared.1"); waitForResponse1(id); - id = mClient->create(item, "com.nokia.shared.2"); + id = create(item, "com.nokia.shared.2"); waitForResponse1(id); } - // Create items in the model. void TestJsonDbCachingListModel::createItem() { + resetWaitFlags(); QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("name", "Arnie"); - int id = mClient->create(item, "com.nokia.shared.1"); + int id = create(item, "com.nokia.shared.1"); waitForResponse1(id); createIndex("name", "string"); @@ -286,25 +240,36 @@ void TestJsonDbCachingListModel::createItem() // now start it working QCOMPARE(listModel->rowCount(), 0); - waitForStateOrTimeout(); + mWaitingForReset = true; + waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); + QCOMPARE(listModel->rowCount(), 1); QCOMPARE(listModel->property("cacheSize").toInt(), 200); - getIndex(0); - QCOMPARE(callbackResponse.toMap().value("_type").toString(), QLatin1String(__FUNCTION__)); - QCOMPARE(callbackResponse.toMap().value("name").toString(), QLatin1String("Arnie")); + QVariant val = getIndex(listModel, 0, 0); + QCOMPARE(val.toString(), QLatin1String(__FUNCTION__)); + val = getIndex(listModel, 0, 2); + QCOMPARE(val.toString(), QLatin1String("Arnie")); item.clear(); item.insert("_type", __FUNCTION__); item.insert("name", "Barney"); - id = mClient->create(item, "com.nokia.shared.1"); - waitForItemChanged(); + mItemsCreated = 0; + id = create(item, "com.nokia.shared.1"); + waitForResponse1(id); + while (!mItemsCreated) { + mWaitingForRowsInserted = true; + waitForExitOrTimeout(); + } + QCOMPARE(mWaitingForRowsInserted, false); QCOMPARE(listModel->rowCount(), 2); - getIndex(1); - QCOMPARE(callbackResponse.toMap().value("_type").toString(), QLatin1String(__FUNCTION__)); - QCOMPARE(callbackResponse.toMap().value("name").toString(), QLatin1String("Barney")); + val = getIndex(listModel, 1, 0); + QCOMPARE(val.toString(), QLatin1String(__FUNCTION__)); + val = getIndex(listModel, 1, 2); + QCOMPARE(val.toString(), QLatin1String("Barney")); deleteModel(listModel); } @@ -312,132 +277,171 @@ void TestJsonDbCachingListModel::createItem() // Populate model of 300 items two partitions. void TestJsonDbCachingListModel::createModelTwoPartitions() { + resetWaitFlags(); QVariantMap item; for (int i=0; i < 300; i = i+2) { item.insert("_type", __FUNCTION__); item.insert("name", QString("Arnie_%1").arg(i)); - int id = mClient->create(item, "com.nokia.shared.1"); + int id = create(item, "com.nokia.shared.1"); waitForResponse1(id); } for (int i=1; i < 300; i = i+2) { item.insert("_type", __FUNCTION__); item.insert("name", QString("Arnie_%1").arg(i)); - int id = mClient->create(item, "com.nokia.shared.2"); + int id = create(item, "com.nokia.shared.2"); waitForResponse1(id); } - createIndex("name", "string"); - QAbstractListModel *listModel = createModel(); if (!listModel) return; QStringList roleNames = (QStringList() << "_type" << "_uuid" << "name"); listModel->setProperty("roleNames", roleNames); + listModel->setProperty("sortOrder", "[/name]"); + listModel->setProperty("cacheSize", 50); listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); connectListModel(listModel); // now start it working QCOMPARE(listModel->rowCount(), 0); - waitForStateOrTimeout(); + mWaitingForReset = true; + waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->rowCount(), 300); deleteModel(listModel); } - - // Create an item and then update it. void TestJsonDbCachingListModel::updateItemClient() { + resetWaitFlags(); QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); - int id = mClient->create(item,"com.nokia.shared.1"); + int id = create(item,"com.nokia.shared.1"); waitForResponse1(id); QAbstractListModel *listModel = createModel(); if (!listModel) return; - listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); QStringList roleNames = (QStringList() << "_type" << "_uuid" << "name"); listModel->setProperty("roleNames", roleNames); + listModel->setProperty("sortOrder", "[/name]"); + listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); connectListModel(listModel); // now start it working QCOMPARE(listModel->rowCount(), 0); - waitForStateOrTimeout(); - QCOMPARE(listModel->rowCount(), 1); + mWaitingForReset = true; + waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); - getIndex(0); - QCOMPARE(callbackResponse.toMap().value("_type").toString(), QLatin1String(__FUNCTION__)); - QCOMPARE(callbackResponse.toMap().value("name").toString(), QLatin1String("Charlie")); + QCOMPARE(listModel->rowCount(), 1); - item.insert("_uuid", mLastUuid); + QVariant val = getIndex(listModel, 0, 0); + QCOMPARE(val.toString(), QLatin1String(__FUNCTION__)); + val = getIndex(listModel, 0, 2); + QCOMPARE(val.toString(), QLatin1String("Charlie")); + + QString lastUuid,lastVersion; + QVariantMap lastItem; + if (lastResult.count()) { + lastItem = lastResult[0].toMap(); + lastUuid = lastItem.value("_uuid").toString(); + lastVersion = lastItem.value("_version").toString(); + } + item.insert("_uuid", lastUuid); item.insert("name", "Baker"); - mWaitingForDataChange = true; - - id = mClient->update(item, "com.nokia.shared.1"); - waitForItemChanged(); + mItemsUpdated = 0; + id = update(item, "com.nokia.shared.1"); + waitForResponseUntil(id); + while (!mItemsUpdated) { + mWaitingForChanged = true; + waitForExitOrTimeout(); + } QCOMPARE(listModel->rowCount(), 1); - getIndex(0); - QCOMPARE(callbackResponse.toMap().value("_type").toString(), QLatin1String(__FUNCTION__)); - QCOMPARE(callbackResponse.toMap().value("name").toString(), QLatin1String("Baker")); + val = getIndex(listModel, 0, 0); + QCOMPARE(val.toString(), QLatin1String(__FUNCTION__)); + val = getIndex(listModel, 0, 2); + QCOMPARE(val.toString(), QLatin1String("Baker")); deleteModel(listModel); } void TestJsonDbCachingListModel::deleteItem() { + resetWaitFlags(); QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); - int id = mClient->create(item, "com.nokia.shared.1"); - waitForResponse1(id); + int id = create(item, "com.nokia.shared.1"); + waitForResponseUntil(id); QAbstractListModel *listModel = createModel(); if (!listModel) return; - listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); QStringList roleNames = (QStringList() << "_type" << "_uuid" << "name"); listModel->setProperty("roleNames", roleNames); + listModel->setProperty("sortOrder", "[/name]"); + listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); connectListModel(listModel); // now start it working - waitForStateOrTimeout(); + mWaitingForReset = true; + waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); + QCOMPARE(listModel->rowCount(), 1); item.insert("name", "Baker"); - id = mClient->create(item, "com.nokia.shared.2"); - waitForResponse1(id); + mItemsCreated = 0; + id = create(item, "com.nokia.shared.2"); + waitForResponseUntil(id); + waitForItemsCreated(1); QCOMPARE(listModel->rowCount(), 2); - mWaitingForRowsRemoved = true; - item.insert("_uuid", mLastUuid); - id = mClient->remove(item, "com.nokia.shared.2"); - waitForItemChanged(true); - + QString lastUuid,lastVersion; + QVariantMap lastItem; + if (lastResult.count()) { + lastItem = lastResult[0].toMap(); + lastUuid = lastItem.value("_uuid").toString(); + lastVersion = lastItem.value("_version").toString(); + } + item.insert("_uuid", lastUuid); + mItemsRemoved = 0; + id = remove(item, "com.nokia.shared.2"); + waitForResponseUntil(id); + + while (!mItemsRemoved) { + mWaitingForRemoved = true; + waitForExitOrTimeout(); + } + QCOMPARE(mWaitingForRemoved, false); QCOMPARE(listModel->rowCount(), 1); - getIndex(0); - QCOMPARE(callbackResponse.toMap().value("_type").toString(), QLatin1String(__FUNCTION__)); - QCOMPARE(callbackResponse.toMap().value("name").toString(), QLatin1String("Charlie")); + QVariant val = getIndex(listModel, 0, 0); + QCOMPARE(val.toString(), QLatin1String(__FUNCTION__)); + val = getIndex(listModel, 0, 2); + QCOMPARE(val.toString(), QLatin1String("Charlie")); deleteModel(listModel); } void TestJsonDbCachingListModel::sortedQuery() { + resetWaitFlags(); int id = 0; for (int i = 0; i < 1000; i++) { QVariantMap item; item.insert("_type", "RandNumber"); item.insert("number", i); - id = mClient->create(item,"com.nokia.shared.2"); + id = create(item,"com.nokia.shared.2"); waitForResponse1(id); } @@ -452,27 +456,31 @@ void TestJsonDbCachingListModel::sortedQuery() rolenames << "_uuid" << "_type" << "number"; listModel->setProperty("roleNames", rolenames); listModel->setProperty("sortOrder", "[/number]"); + listModel->setProperty("cacheSize", 20); listModel->setProperty("query", "[?_type=\"RandNumber\"]"); - waitForStateOrTimeout(); + mWaitingForReset = true; + waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->property("sortOrder").toString(), QString("[/number]")); QCOMPARE(listModel->rowCount(), 1000); for (int i = 0; i < 1000; i++) { - getIndex(i); - QCOMPARE(callbackResponse.toMap().value("number").toInt(), i); + QVariant num = getIndex(listModel, i, 2); + QCOMPARE(num.toInt(), i); } - listModel->setProperty("sortOrder", "[\\number]"); - waitForStateOrTimeout(); + mWaitingForReset = true; + waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->property("sortOrder").toString(), QString("[\\number]")); QCOMPARE(listModel->rowCount(), 1000); for (int i = 0; i < 1000; i++) { - getIndex(i); - QCOMPARE(callbackResponse.toMap().value("number").toInt(), 999-i); + QVariant num = getIndex(listModel, i, 2); + QCOMPARE(num.toInt(), 999-i); } listModel->setProperty("query", QString()); @@ -494,13 +502,14 @@ bool greaterThan(const QString &s1, const QString &s2) void TestJsonDbCachingListModel::ordering() { + resetWaitFlags(); for (int i = 9; i >= 1; --i) { QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); item.insert("ordering", QString::number(i)); - int id = mClient->create(item, "com.nokia.shared.2"); - waitForResponse1(id); + int id = create(item, "com.nokia.shared.2"); + waitForResponseUntil(id); } QAbstractListModel *listModel = createModel(); @@ -509,22 +518,24 @@ void TestJsonDbCachingListModel::ordering() createIndex("ordering", "string"); listModel->setProperty("sortOrder", "[/ordering]"); - listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); QStringList roleNames = (QStringList() << "_type" << "_uuid" << "name" << "ordering"); listModel->setProperty("roleNames", roleNames); + listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); connectListModel(listModel); // now start it working QCOMPARE(listModel->rowCount(), 0); - waitForStateOrTimeout(); + mWaitingForReset = true; + waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); + mItemsUpdated = 0; QStringList expectedOrder = QStringList() << "1" << "2" << "3" << "4" << "5" << "6" << "7" << "8" << "9"; QCOMPARE(getOrderValues(listModel), expectedOrder); { - getIndex(4); - QVariant uuid = callbackResponse.toMap().value("_uuid"); + QVariant uuid = getIndex(listModel, 4, 1); QVERIFY(!uuid.toString().isEmpty()); QVariantMap item; @@ -532,16 +543,22 @@ void TestJsonDbCachingListModel::ordering() item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); item.insert("ordering", "99"); // move it to the end - mClient->update(item, "com.nokia.shared.2"); + int id = update(item, "com.nokia.shared.2"); + waitForResponseUntil(id); + } + + while (!mItemsUpdated) { + mWaitingForChanged = true; + waitForExitOrTimeout(); } - waitForItemChanged(); + QCOMPARE(mWaitingForChanged, false); + mItemsUpdated = 0; expectedOrder = QStringList() << "1" << "2" << "3" << "4" << "6" << "7" << "8" << "9" << "99"; QCOMPARE(getOrderValues(listModel), expectedOrder); { - getIndex(8); - QVariant uuid =callbackResponse.toMap().value("_uuid"); + QVariant uuid = getIndex(listModel, 8, 1); QVERIFY(!uuid.toString().isEmpty()); QVariantMap item; @@ -549,16 +566,21 @@ void TestJsonDbCachingListModel::ordering() item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); item.insert("ordering", "22"); // move it after "2" - mClient->update(item, "com.nokia.shared.2"); + int id = update(item, "com.nokia.shared.2"); + waitForResponseUntil(id); } - waitForItemChanged(); + while (!mItemsUpdated) { + mWaitingForChanged = true; + waitForExitOrTimeout(); + } + QCOMPARE(mWaitingForChanged, false); + mItemsUpdated = 0; expectedOrder = QStringList() << "1" << "2" << "22" << "3" << "4" << "6" << "7" << "8" << "9"; QCOMPARE(getOrderValues(listModel), expectedOrder); { - getIndex(5); - QVariant uuid =callbackResponse.toMap().value("_uuid"); + QVariant uuid = getIndex(listModel, 5, 1); QVERIFY(!uuid.toString().isEmpty()); QVariantMap item; @@ -566,9 +588,14 @@ void TestJsonDbCachingListModel::ordering() item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); item.insert("ordering", "0"); // move it to the beginning - mClient->update(item, "com.nokia.shared.2"); + int id = update(item, "com.nokia.shared.2"); + waitForResponseUntil(id); + } + while (!mItemsUpdated) { + mWaitingForChanged = true; + waitForExitOrTimeout(); } - waitForItemChanged(); + QCOMPARE(mWaitingForChanged, false); expectedOrder = QStringList() << "0" << "1" << "2" << "22" << "3" << "4" << "7" << "8" << "9"; @@ -576,7 +603,9 @@ void TestJsonDbCachingListModel::ordering() listModel->setProperty("sortOrder", "[\\ordering]"); - waitForStateOrTimeout(); + mWaitingForReset = true; + waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QStringList reverseOrder = expectedOrder; qSort(reverseOrder.begin(), reverseOrder.end(), greaterThan); @@ -584,17 +613,18 @@ void TestJsonDbCachingListModel::ordering() QCOMPARE(getOrderValues(listModel), reverseOrder); listModel->setProperty("sortOrder", "[/ordering]"); - waitForStateOrTimeout(); - + mWaitingForReset = true; + waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(getOrderValues(listModel), expectedOrder); deleteModel(listModel); - } void TestJsonDbCachingListModel::checkRemoveNotification() { + resetWaitFlags(); QVariantList itemList; for (int i = 0; i < 50; i++) { QVariantMap item; @@ -603,7 +633,7 @@ void TestJsonDbCachingListModel::checkRemoveNotification() item.insert("order", i); itemList << item; } - int id = mClient->create(itemList,"com.nokia.shared.2"); + int id = create(itemList,"com.nokia.shared.2"); waitForResponse1(id); { @@ -614,56 +644,63 @@ void TestJsonDbCachingListModel::checkRemoveNotification() connectListModel(listModel); listModel->setProperty("sortOrder", "[/order]"); - listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); QStringList roleNames = (QStringList() << "_type" << "_uuid" << "_version"<< "name" << "order"); listModel->setProperty("roleNames", roleNames); + listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); - waitForStateOrTimeout(); + mWaitingForReset = true; + waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->rowCount(), 50); - getIndex(0); - QVariant result = callbackResponse.toMap().value("order"); + QVariant result = getIndex(listModel, 0, 4); QVERIFY(result.isValid()); QCOMPARE(result.toInt(), 0); - getIndex(9); - result = callbackResponse.toMap().value("order"); + result = getIndex(listModel, 9, 4); QVERIFY(result.isValid()); QCOMPARE(result.toInt(), 9); //Remove item at 0 QVariantMap item; - getIndex(0); - item.insert("_uuid", callbackResponse.toMap().value("_uuid")); - item.insert("_version", callbackResponse.toMap().value("_version")); - id = mClient->remove(item, "com.nokia.shared.2"); - waitForItemChanged(true); + QVariant uuid = getIndex(listModel, 0, 1); + item.insert("_uuid", uuid); + QVariant version = getIndex(listModel, 0, 2); + item.insert("_version", version); + mItemsRemoved = 0; + id = remove(item, "com.nokia.shared.2"); + waitForResponseUntil(id); + waitForItemsRemoved(1); QCOMPARE(listModel->rowCount(), 49); - getIndex(9); - result = callbackResponse.toMap().value("order"); + + result = getIndex(listModel, 9, 4); QVERIFY(result.isValid()); QCOMPARE(result.toInt(), 10); //Remove item at 9 - getIndex(9); - item.insert("_uuid", callbackResponse.toMap().value("_uuid")); - item.insert("_version", callbackResponse.toMap().value("_version")); - id = mClient->remove(item, "com.nokia.shared.2"); - waitForItemChanged(true); + uuid = getIndex(listModel, 9, 1); + item.insert("_uuid", uuid); + version = getIndex(listModel, 9, 2); + item.insert("_version", version); + mItemsRemoved = 0; + id = remove(item, "com.nokia.shared.2"); + waitForResponseUntil(id); + waitForItemsRemoved(1); QCOMPARE(listModel->rowCount(), 48); - getIndex(9); - result = callbackResponse.toMap().value("order"); + result = getIndex(listModel, 9, 4); QVERIFY(result.isValid()); QCOMPARE(result.toInt(), 11); //Remove item at 4 - getIndex(4); - item.insert("_uuid", callbackResponse.toMap().value("_uuid")); - item.insert("_version", callbackResponse.toMap().value("_version")); - id = mClient->remove(item, "com.nokia.shared.2"); - waitForItemChanged(true); + uuid = getIndex(listModel, 4, 1); + item.insert("_uuid", uuid); + version = getIndex(listModel, 9, 2); + item.insert("_version", version); + mItemsRemoved = 0; + id = remove(item, "com.nokia.shared.2"); + waitForResponseUntil(id); + waitForItemsRemoved(1); QCOMPARE(listModel->rowCount(), 47); - getIndex(4); - result = callbackResponse.toMap().value("order"); + result = getIndex(listModel, 4, 4); QVERIFY(result.isValid()); QCOMPARE(result.toInt(), 6); @@ -673,6 +710,7 @@ void TestJsonDbCachingListModel::checkRemoveNotification() void TestJsonDbCachingListModel::checkUpdateNotification() { + resetWaitFlags(); QVariantList itemList; for (int i = 0; i < 50; i++) { if (i%2) @@ -683,7 +721,7 @@ void TestJsonDbCachingListModel::checkUpdateNotification() item.insert("order", i); itemList << item; } - int id = mClient->create(itemList, "com.nokia.shared.1"); + int id = create(itemList, "com.nokia.shared.1"); waitForResponse1(id); { @@ -698,106 +736,132 @@ void TestJsonDbCachingListModel::checkUpdateNotification() listModel->setProperty("roleNames", roleNames); listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); - waitForStateOrTimeout(); + mWaitingForReset = true; + waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->rowCount(), 25); - getIndex(0); - QVariant result = callbackResponse.toMap().value("order"); + QVariant result = getIndex(listModel, 0, 4); QVERIFY(result.isValid()); QCOMPARE(result.toInt(), 0); - getIndex(9); - result = callbackResponse.toMap().value("order"); + result = getIndex(listModel, 9, 4); QVERIFY(result.isValid()); QCOMPARE(result.toInt(), 18); //Update item at 0 QVariantMap item; - getIndex(0); - item.insert("_uuid", callbackResponse.toMap().value("_uuid")); - item.insert("_type", callbackResponse.toMap().value("_type")); - item.insert("name", callbackResponse.toMap().value("name")); + QVariant uuid = getIndex(listModel, 0, 1); + item.insert("_uuid", uuid); + QVariant _type = getIndex(listModel, 0, 0); + item.insert("_type", _type); + QVariant name = getIndex(listModel, 0, 3); + item.insert("name", name); item.insert("order", 1); - id = mClient->update(item, "com.nokia.shared.1"); - waitForItemChanged(); + mItemsUpdated = 0; + id = update(item, "com.nokia.shared.1"); + waitForResponseUntil(id); + while (!mItemsUpdated) { + mWaitingForChanged = true; + waitForExitOrTimeout(); + } QCOMPARE(listModel->rowCount(), 25); - getIndex(0); - result = callbackResponse.toMap().value("order"); + result = getIndex(listModel, 0, 4); QVERIFY(result.isValid()); QCOMPARE(result.toInt(), 1); - getIndex(9); - result = callbackResponse.toMap().value("order"); + result = getIndex(listModel, 9, 4); QVERIFY(result.isValid()); QCOMPARE(result.toInt(), 18); //Update item at 9 item.clear(); - getIndex(9); - item.insert("_uuid", callbackResponse.toMap().value("_uuid")); - item.insert("_type", callbackResponse.toMap().value("_type")); - item.insert("name", callbackResponse.toMap().value("name")); + uuid = getIndex(listModel, 9, 1); + item.insert("_uuid", uuid); + _type = getIndex(listModel, 9, 0); + item.insert("_type", _type); + name = getIndex(listModel, 9, 3); + item.insert("name", name); item.insert("order", 19); - id = mClient->update(item,"com.nokia.shared.1"); - waitForItemChanged(); + mItemsUpdated = 0; + id = update(item,"com.nokia.shared.1"); + waitForResponseUntil(id); + while (!mItemsUpdated) { + mWaitingForChanged = true; + waitForExitOrTimeout(); + } item.clear(); - getIndex(9); - item.insert("_uuid", callbackResponse.toMap().value("_uuid")); - item.insert("_type", callbackResponse.toMap().value("_type")); - item.insert("name", callbackResponse.toMap().value("name")); + uuid = getIndex(listModel, 9, 1); + item.insert("_uuid", uuid); + _type = getIndex(listModel, 9, 0); + item.insert("_type", _type); + name = getIndex(listModel, 9, 3); + item.insert("name", name); item.insert("order", 19); - id = mClient->update(item,"com.nokia.shared.1"); - waitForItemChanged(); + mItemsUpdated = 0; + id = update(item,"com.nokia.shared.1"); + waitForResponseUntil(id); + while (!mItemsUpdated) { + mWaitingForChanged = true; + waitForExitOrTimeout(); + } QCOMPARE(listModel->rowCount(), 25); - getIndex(0); - result = callbackResponse.toMap().value("order"); + result = getIndex(listModel, 0, 4); QVERIFY(result.isValid()); QCOMPARE(result.toInt(), 1); - getIndex(9); - result = callbackResponse.toMap().value("order"); + result = getIndex(listModel, 9, 4); QVERIFY(result.isValid()); QCOMPARE(result.toInt(), 19); //Update item at 9 - getIndex(9); - item.insert("_uuid", callbackResponse.toMap().value("_uuid")); - item.insert("_type", callbackResponse.toMap().value("_type")); - item.insert("name", callbackResponse.toMap().value("name")); + item.clear(); + uuid = getIndex(listModel, 9, 1); + item.insert("_uuid", uuid); + _type = getIndex(listModel, 9, 0); + item.insert("_type", _type); + name = getIndex(listModel, 9, 3); + item.insert("name", name); item.insert("order", 59); - id = mClient->update(item, "com.nokia.shared.1"); - waitForItemChanged(); - + mItemsUpdated = 0; + id = update(item, "com.nokia.shared.1"); + waitForResponseUntil(id); + while (!mItemsUpdated) { + mWaitingForChanged = true; + waitForExitOrTimeout(); + } QCOMPARE(listModel->rowCount(), 25); - getIndex(0); - result = callbackResponse.toMap().value("order"); + result = getIndex(listModel, 0, 4); QVERIFY(result.isValid()); QCOMPARE(result.toInt(), 1); - getIndex(9); - result = callbackResponse.toMap().value("order"); + result = getIndex(listModel, 9, 4); QVERIFY(result.isValid()); QCOMPARE(result.toInt(), 20); //Update item at 8 - getIndex(8); - item.insert("_uuid", callbackResponse.toMap().value("_uuid")); - item.insert("_type", callbackResponse.toMap().value("_type")); - item.insert("name", callbackResponse.toMap().value("name")); + item.clear(); + uuid = getIndex(listModel, 8, 1); + item.insert("_uuid", uuid); + _type = getIndex(listModel, 8, 0); + item.insert("_type", _type); + name = getIndex(listModel, 8, 3); + item.insert("name", name); item.insert("order", 17); - id = mClient->update(item, "com.nokia.shared.1"); - waitForItemChanged(); - + mItemsUpdated = 0; + id = update(item, "com.nokia.shared.1"); + waitForResponseUntil(id); + while (!mItemsUpdated) { + mWaitingForChanged = true; + waitForExitOrTimeout(); + } QCOMPARE(listModel->rowCount(), 25); - getIndex(8); - result = callbackResponse.toMap().value("order"); + result = getIndex(listModel, 8, 4); QVERIFY(result.isValid()); QCOMPARE(result.toInt(), 17); - getIndex(0); - result = callbackResponse.toMap().value("order"); + result = getIndex(listModel, 0, 4); QVERIFY(result.isValid()); QCOMPARE(result.toInt(), 1); - getIndex(9); - result = callbackResponse.toMap().value("order"); + result = getIndex(listModel, 9, 4); QVERIFY(result.isValid()); QCOMPARE(result.toInt(), 20); @@ -807,15 +871,16 @@ void TestJsonDbCachingListModel::checkUpdateNotification() void TestJsonDbCachingListModel::totalRowCount() { + resetWaitFlags(); int id = 0; QVariantList insertedItems; for (int i = 0; i < 10; i++) { QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("order", i); - id = mClient->create(item, "com.nokia.shared.1"); + id = create(item, "com.nokia.shared.1"); waitForResponse1(id); - insertedItems << mData; + insertedItems << lastResult; } QAbstractListModel *listModel = createModel(); @@ -824,38 +889,47 @@ void TestJsonDbCachingListModel::totalRowCount() connectListModel(listModel); - listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); QStringList roleNames = (QStringList() << "_type" << "_uuid" << "order"); listModel->setProperty("roleNames", roleNames); + listModel->setProperty("sortOrder", "[/order]"); + listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); - waitForStateOrTimeout(); + mWaitingForReset = true; + waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->rowCount(), 10); + mItemsCreated = 0; for (int i = 10; i < 50; i++) { QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("order", i); - mClient->create(item, "com.nokia.shared.2"); + id = create(item, "com.nokia.shared.2"); + waitForResponse1(id); } waitForItemsCreated(40); + //wait for the last one + if (id != lastRequestId) + waitForResponse1(id); QCOMPARE(listModel->rowCount(), 50); - - createIndex("order", "number"); - // Change sort order listModel->setProperty("sortOrder", "[\\order]"); + + mWaitingForStateChanged = true; waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); QCOMPARE(listModel->rowCount(), 50); // Delete the first 10 items + mItemsRemoved = 0; foreach (QVariant item, insertedItems) { - mWaitingForRowsRemoved = true; - id = mClient->remove(item.toMap(), "com.nokia.shared.1"); - waitForItemChanged(true); + id = remove(item.toMap(), "com.nokia.shared.1"); + waitForResponse1(id); } + waitForItemsRemoved(10); QCOMPARE(listModel->rowCount(), 40); @@ -864,15 +938,16 @@ void TestJsonDbCachingListModel::totalRowCount() void TestJsonDbCachingListModel::listProperty() { + resetWaitFlags(); QVariant jsonData = readJsonFile(findFile("list-objects.json")).toVariant(); QVariantList itemList = jsonData.toList(); int id = 0; for (int i = 0; i < itemList.count()/2; i++) { - id = mClient->create(itemList[i].toMap(), "com.nokia.shared.1"); + id = create(itemList[i].toMap(), "com.nokia.shared.1"); waitForResponse1(id); } for (int i = itemList.count()/2; i < itemList.count(); i++) { - id = mClient->create(itemList[i].toMap(), "com.nokia.shared.2"); + id = create(itemList[i].toMap(), "com.nokia.shared.2"); waitForResponse1(id); } @@ -885,21 +960,28 @@ void TestJsonDbCachingListModel::listProperty() connectListModel(listModel); QString type = itemList[0].toMap()["_type"].toString(); listModel->setProperty("sortOrder", "[/features.0.properties.0.description]"); - listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(type)); QStringList roleNames = (QStringList() << "_type" << "_uuid" << "features.0.properties.0.description"<< "features.0.feature"); listModel->setProperty("roleNames", roleNames); + listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(type)); - waitForStateOrTimeout(); + mWaitingForReset = true; + waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->rowCount(), itemList.count()); - getIndex(0); - QCOMPARE(callbackResponse.toMap().value("_type").toString(), type); - QCOMPARE(callbackResponse.toMap().value("features").toList().at(0).toMap().value("properties").toList().at(0).toMap().value("description").toString(), QLatin1String("Facebook account provider")); - QCOMPARE(callbackResponse.toMap().value("features").toList().at(0).toMap().value("feature").toString(), QLatin1String("provide Facebook")); - getIndex(1); - QCOMPARE(callbackResponse.toMap().value("_type").toString(), type); - QCOMPARE(callbackResponse.toMap().value("features").toList().at(0).toMap().value("properties").toList().at(0).toMap().value("description").toString(), QLatin1String("Gmail account provider")); - QCOMPARE(callbackResponse.toMap().value("features").toList().at(0).toMap().value("feature").toString(), QLatin1String("provide Gmail")); + QVariant _type = getIndex(listModel, 0, 0); + QCOMPARE(_type.toString(), type); + QVariant featuresDesc = getIndex(listModel, 0, 2); + QCOMPARE(featuresDesc.toString(), QLatin1String("Facebook account provider")); + QVariant features = getIndex(listModel, 0, 3); + QCOMPARE(features.toString(), QLatin1String("provide Facebook")); + + _type = getIndex(listModel, 1, 0); + QCOMPARE(_type.toString(), type); + featuresDesc = getIndex(listModel, 1, 2); + QCOMPARE(featuresDesc.toString(), QLatin1String("Gmail account provider")); + features = getIndex(listModel, 1, 3); + QCOMPARE(features.toString(), QLatin1String("provide Gmail")); deleteModel(listModel); @@ -909,33 +991,42 @@ void TestJsonDbCachingListModel::listProperty() connectListModel(listModel); type = itemList[0].toMap()["_type"].toString(); listModel->setProperty("sortOrder", "[/features.0.properties.0.description]"); - listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(type)); roleNames.clear(); roleNames = (QStringList() << "_type" << "_uuid" << "features[0].properties[0].description"<< "features[0].supported[0]"); listModel->setProperty("roleNames", roleNames); - waitForStateOrTimeout(); + listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(type)); + + mWaitingForReset = true; + waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->rowCount(), itemList.count()); - getIndex(0); - QCOMPARE(callbackResponse.toMap().value("_type").toString(), type); - QCOMPARE(callbackResponse.toMap().value("features").toList().at(0).toMap().value("properties").toList().at(0).toMap().value("description").toString(), QLatin1String("Facebook account provider")); - QCOMPARE(callbackResponse.toMap().value("features").toList().at(0).toMap().value("supported").toList().at(0).toString(), QLatin1String("share")); - getIndex(1); - QCOMPARE(callbackResponse.toMap().value("_type").toString(), type); - QCOMPARE(callbackResponse.toMap().value("features").toList().at(0).toMap().value("properties").toList().at(0).toMap().value("description").toString(), QLatin1String("Gmail account provider")); - QCOMPARE(callbackResponse.toMap().value("features").toList().at(0).toMap().value("supported").toList().at(0).toString(), QLatin1String("share")); + _type = getIndex(listModel, 0, 0); + QCOMPARE(_type.toString(), type); + featuresDesc = getIndex(listModel, 0, 2); + QCOMPARE(featuresDesc.toString(), QLatin1String("Facebook account provider")); + features = getIndex(listModel, 0, 3); + QCOMPARE(features.toString(), QLatin1String("share")); + + _type = getIndex(listModel, 1, 0); + QCOMPARE(_type.toString(), type); + featuresDesc = getIndex(listModel, 1, 2); + QCOMPARE(featuresDesc.toString(), QLatin1String("Gmail account provider")); + features = getIndex(listModel, 1, 3); + QCOMPARE(features.toString(), QLatin1String("share")); deleteModel(listModel); } void TestJsonDbCachingListModel::changeQuery() { + resetWaitFlags(); QVariantMap item; for (int i=0; i < 10; i++) { item.insert("_type", __FUNCTION__); item.insert("name", QString("Arnie_%1").arg(i)); - int id = mClient->create(item, "com.nokia.shared.1"); + int id = create(item, "com.nokia.shared.1"); waitForResponse1(id); } @@ -950,7 +1041,9 @@ void TestJsonDbCachingListModel::changeQuery() listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); connectListModel(listModel); - waitForStateOrTimeout(); + mWaitingForReset = true; + waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->rowCount(), 10); QCOMPARE(listModel->property("query").toString(), QString("[?_type=\"%1\"]").arg(__FUNCTION__)); @@ -966,7 +1059,10 @@ void TestJsonDbCachingListModel::changeQuery() QCOMPARE(listModel->property("query").toString(), QString("")); listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); - waitForStateOrTimeout(); + + mWaitingForReset = true; + waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->rowCount(), 10); QCOMPARE(listModel->property("query").toString(), QString("[?_type=\"%1\"]").arg(__FUNCTION__)); @@ -976,10 +1072,11 @@ void TestJsonDbCachingListModel::changeQuery() void TestJsonDbCachingListModel::indexOfUuid() { + resetWaitFlags(); QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("name", QString("Arnie_0")); - int id = mClient->create(item, "com.nokia.shared.1"); + int id = create(item, "com.nokia.shared.1"); waitForResponse1(id); createIndex("name", "string"); @@ -993,23 +1090,28 @@ void TestJsonDbCachingListModel::indexOfUuid() listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); connectListModel(listModel); - waitForStateOrTimeout(); + mWaitingForReset = true; + waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->rowCount(), 1); - getIndex(0); - QCOMPARE(callbackResponse.toMap().value("name").toString(), QString("Arnie_0")); - QCOMPARE(indexOf(listModel, callbackResponse.toMap().value("_uuid").toString()), 0); + QVariant name = getIndex(listModel, 0, 2); + QCOMPARE(name.toString(), QString("Arnie_0")); + QVariant uuid = getIndex(listModel, 0, 1); + QCOMPARE(indexOf(listModel, uuid.toString()), 0); item.insert("_type", __FUNCTION__); item.insert("name", QString("Arnie_1")); - id = mClient->create(item, "com.nokia.shared.1"); - + mItemsCreated = 0; + id = create(item, "com.nokia.shared.1"); + waitForResponse1(id); waitForItemsCreated(1); QCOMPARE(listModel->rowCount(), 2); - getIndex(1); - QCOMPARE(callbackResponse.toMap().value("name").toString(), QString("Arnie_1")); - QCOMPARE(indexOf(listModel, callbackResponse.toMap().value("_uuid").toString()), 1); + name = getIndex(listModel, 1, 2); + QCOMPARE(name.toString(), QString("Arnie_1")); + uuid = getIndex(listModel, 1, 1); + QCOMPARE(indexOf(listModel, uuid.toString()), 1); QCOMPARE(indexOf(listModel, "notValid"), -1); deleteModel(listModel); @@ -1017,15 +1119,15 @@ void TestJsonDbCachingListModel::indexOfUuid() void TestJsonDbCachingListModel::roleNames() { + resetWaitFlags(); QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("name", QString("Arnie")); item.insert("friend", QString("Bert")); - int id = mClient->create(item, "com.nokia.shared.1"); + int id = create(item, "com.nokia.shared.1"); waitForResponse1(id); - QAbstractListModel *listModel = createModel(); if (!listModel) return; @@ -1034,7 +1136,9 @@ void TestJsonDbCachingListModel::roleNames() listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); connectListModel(listModel); - waitForStateOrTimeout(); + mWaitingForReset = true; + waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->rowCount(), 1); @@ -1058,11 +1162,12 @@ void TestJsonDbCachingListModel::roleNames() void TestJsonDbCachingListModel::getItemNotInCache() { + resetWaitFlags(); QVariantMap item; - for (int i=0; i < 300; i++) { + for (int i=0; i < 3000; i++) { item.insert("_type", __FUNCTION__); item.insert("number", i); - int id = mClient->create(item, "com.nokia.shared.1"); + int id = create(item, "com.nokia.shared.1"); waitForResponse1(id); } @@ -1070,7 +1175,7 @@ void TestJsonDbCachingListModel::getItemNotInCache() QAbstractListModel *listModel = createModel(); if (!listModel) return; - listModel->setProperty("cacheSize", 100); + listModel->setProperty("cacheSize", 50); listModel->setProperty("sortOrder", "[/number]"); QStringList roleNames = (QStringList() << "_type" << "_uuid" << "number"); listModel->setProperty("roleNames", roleNames); @@ -1080,47 +1185,51 @@ void TestJsonDbCachingListModel::getItemNotInCache() // now start it working QCOMPARE(listModel->rowCount(), 0); - waitForStateOrTimeout(); - QCOMPARE(listModel->rowCount(), 300); - QCOMPARE(listModel->property("cacheSize").toInt(), 100); - - getIndex(100); - QCOMPARE(callbackResponse.toMap().value("number").toInt(), 100); - getIndex(151); - QCOMPARE(callbackResponse.toMap().value("number").toInt(), 151); - getIndex(202); - QCOMPARE(callbackResponse.toMap().value("number").toInt(), 202); - getIndex(255); - QCOMPARE(callbackResponse.toMap().value("number").toInt(), 255); - getIndex(20); - QCOMPARE(callbackResponse.toMap().value("number").toInt(), 20); + mWaitingForReset = true; + waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); - deleteModel(listModel); -} + QCOMPARE(listModel->rowCount(), 3000); + QVariant number = getIndex(listModel, 2967, 2); + QCOMPARE(number.toInt(), 2967); + number = getIndex(listModel, 100, 2); + QCOMPARE(number.toInt(), 100); + number = getIndex(listModel, 1701, 2); + QCOMPARE(number.toInt(), 1701); + number = getIndex(listModel, 20, 2); + QCOMPARE(number.toInt(), 20); + + deleteModel(listModel); +} QStringList TestJsonDbCachingListModel::getOrderValues(QAbstractListModel *listModel) { QStringList vals; for (int i = 0; i < listModel->rowCount(); ++i) { - getIndex(i); - vals << callbackResponse.toMap().value("ordering").toString(); + vals << getIndex(listModel, i, 3).toString(); } return vals; } void TestJsonDbCachingListModel::modelReset() { - mWaitingForReset = false; - mEventLoop2.exit(0); + if (mWaitingForReset) { + mWaitingForReset = false; + eventLoop1.exit(0); + } } void TestJsonDbCachingListModel::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { Q_UNUSED(topLeft); Q_UNUSED(bottomRight); - mWaitingForDataChange = false; + mItemsUpdated++; + if (mWaitingForChanged) { + mWaitingForChanged = false; + eventLoop1.exit(0); + } } void TestJsonDbCachingListModel::rowsInserted(const QModelIndex &parent, int first, int last) @@ -1128,8 +1237,11 @@ void TestJsonDbCachingListModel::rowsInserted(const QModelIndex &parent, int fir Q_UNUSED(parent); Q_UNUSED(first); Q_UNUSED(last); - mItemsCreated++; - mEventLoop2.exit(0); + mItemsCreated += last-first+1; + if (mWaitingForRowsInserted) { + mWaitingForRowsInserted = false; + eventLoop1.exit(0); + } } void TestJsonDbCachingListModel::rowsRemoved(const QModelIndex &parent, int first, int last) @@ -1137,7 +1249,11 @@ void TestJsonDbCachingListModel::rowsRemoved(const QModelIndex &parent, int firs Q_UNUSED(parent); Q_UNUSED(first); Q_UNUSED(last); - mWaitingForRowsRemoved = false; + mItemsRemoved += last-first+1; + if (mWaitingForRemoved) { + mWaitingForRemoved = false; + eventLoop1.exit(0); + } } void TestJsonDbCachingListModel::rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row ) @@ -1153,83 +1269,125 @@ void TestJsonDbCachingListModel::stateChanged() { // only exit on ready state. QAbstractListModel *model = qobject_cast<QAbstractListModel *>(sender()); - if (model->property("state") == 2) { + if (model->property("state").toInt() == 2 && mWaitingForStateChanged) { mWaitingForStateChanged = false; - mEventLoop2.exit(0); + eventLoop1.exit(0); } } void TestJsonDbCachingListModel::waitForItemsCreated(int items) { - mTimeoutCalled = false; + mTimedOut = false; QTimer timer; QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); - QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit())); - timer.start(mClientTimeout); - mElapsedTimer.start(); + timer.start(clientTimeout); + elapsedTimer.start(); - mItemsCreated = 0; - while (mItemsCreated != items && !mTimeoutCalled) - mEventLoop2.processEvents(QEventLoop::AllEvents, mClientTimeout); + while (!mTimedOut && mItemsCreated != items) { + mWaitingForRowsInserted = true; + eventLoop1.exec(QEventLoop::AllEvents); + } + if (mTimedOut) + qDebug () << "waitForItemsCreated Timed out"; +} + +void TestJsonDbCachingListModel::waitForItemsRemoved(int items) +{ + mTimedOut = false; + QTimer timer; + QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); + timer.start(clientTimeout); + elapsedTimer.start(); + + while (!mTimedOut && mItemsRemoved != items) { + mWaitingForRowsInserted = true; + eventLoop1.exec(QEventLoop::AllEvents); + } + if (mTimedOut) + qDebug () << "waitForItemsRemoved Timed out"; } void TestJsonDbCachingListModel::waitForExitOrTimeout() { - mTimeoutCalled = false; QTimer timer; QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); - QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit())); - timer.start(mClientTimeout); - mElapsedTimer.start(); - mEventLoop2.exec(QEventLoop::AllEvents); + timer.start(clientTimeout); + elapsedTimer.start(); + eventLoop1.exec(QEventLoop::AllEvents); } void TestJsonDbCachingListModel::waitForStateOrTimeout() { - mTimeoutCalled = false; + mTimedOut = false; QTimer timer; QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); - QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit())); - timer.start(mClientTimeout); - mElapsedTimer.start(); + timer.start(clientTimeout); + elapsedTimer.start(); - mWaitingForStateChanged = true; - while (mWaitingForStateChanged && !mTimeoutCalled) - mEventLoop2.processEvents(QEventLoop::AllEvents, mClientTimeout); + while (mWaitingForStateChanged && !mTimedOut) { + eventLoop1.exec(QEventLoop::AllEvents); + } + if (mTimedOut) + qDebug () << "waitForStateOrTimeout Timed out"; } void TestJsonDbCachingListModel::timeout() { - ClientWrapper::timeout(); - mTimeoutCalled = true; + qDebug () << "TestJsonDbCachingListModel::timeout()"; + RequestWrapper::timeout(); mTimedOut = true; + eventLoop1.quit(); +} + +void TestJsonDbCachingListModel::resetWaitFlags() +{ + mItemsCreated = 0; + mItemsUpdated = 0; + mItemsRemoved = 0; + mWaitingForStateChanged = false; + mWaitingForRowsInserted = false; + mWaitingForReset = false; + mWaitingForChanged = false; + mWaitingForRemoved = false; } void TestJsonDbCachingListModel::waitForItemChanged(bool waitForRemove) { - mTimeoutCalled = false; + mTimedOut = false; QTimer timer; QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); - QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit())); - timer.start(mClientTimeout); - mElapsedTimer.start(); + timer.start(clientTimeout); + elapsedTimer.start(); - mWaitingForRowsRemoved = true; - mWaitingForDataChange = true; + mWaitingForRemoved = true; + mWaitingForChanged = true; mItemsCreated = 0; mWaitingForReset = true; + mWaitingForStateChanged = true; bool waitMore = true; - while (waitMore && !mTimeoutCalled) { - if (!mWaitingForDataChange) + while (waitMore && !mTimedOut) { + if (!mWaitingForChanged) { + //qDebug() << "waitForItemChanged: mWaitingForChanged"; + break; + } + if (!mWaitingForStateChanged) { + //qDebug() << "waitForItemChanged: mWaitingForStateChanged"; break; - if (mItemsCreated) + } + if (mItemsCreated){ + //qDebug() << "waitForItemChanged: mItemsCreated"; break; - if (!mWaitingForReset) + } + if (!mWaitingForReset){ + //qDebug() << "waitForItemChanged: mWaitingForReset"; break; - if (waitForRemove && !mWaitingForRowsRemoved) + } + if (waitForRemove && !mWaitingForRemoved){ + //qDebug() << "waitForItemChanged: mWaitingForRemoved"; break; - mEventLoop2.processEvents(QEventLoop::AllEvents); + } + eventLoop1.exec(QEventLoop::AllEvents); } } QTEST_MAIN(TestJsonDbCachingListModel) diff --git a/tests/auto/jsondbcachinglistmodel/testjsondbcachinglistmodel.h b/tests/auto/jsondbcachinglistmodel/testjsondbcachinglistmodel.h index cc1f1422..cfd1813e 100644 --- a/tests/auto/jsondbcachinglistmodel/testjsondbcachinglistmodel.h +++ b/tests/auto/jsondbcachinglistmodel/testjsondbcachinglistmodel.h @@ -41,22 +41,9 @@ #ifndef TestJsonDbCachingListModel_H #define TestJsonDbCachingListModel_H -#include <QCoreApplication> -#include <QList> -#include <QTest> -#include <QFile> -#include <QProcess> -#include <QEventLoop> -#include <QDebug> -#include <QLocalSocket> -#include <QTimer> - -#include <jsondb-client.h> -#include <jsondb-error.h> - #include <QAbstractListModel> -#include "clientwrapper.h" -#include "../../shared/qmltestutil.h" +#include "requestwrapper.h" +#include "qmltestutil.h" QT_BEGIN_NAMESPACE class QQmlEngine; @@ -73,14 +60,10 @@ public: ~ModelData(); QQmlEngine *engine; QQmlComponent *component; - QQmlComponent *partitionComponent1; - QQmlComponent *partitionComponent2; QObject *model; - QObject *partition1; - QObject *partition2; }; -class TestJsonDbCachingListModel: public ClientWrapper +class TestJsonDbCachingListModel: public RequestWrapper { Q_OBJECT public: @@ -98,15 +81,10 @@ public slots: void modelReset(); void stateChanged(); - void callbackSlot(QVariant error, QVariant response); - - -protected slots: - void timeout(); - private slots: void initTestCase(); void cleanupTestCase(); + void createItem(); void createModelTwoPartitions(); void updateItemClient(); @@ -121,40 +99,37 @@ private slots: void indexOfUuid(); void roleNames(); void getItemNotInCache(); - +public: + void timeout(); private: void waitForExitOrTimeout(); void waitForItemsCreated(int items); + void waitForItemsRemoved(int items); void waitForStateOrTimeout(); void waitForItemChanged(bool waitForRemove = false); QStringList getOrderValues(QAbstractListModel *listModel); - void getIndex(int index); + QVariant getIndex(QAbstractListModel *model, int index, int role); void createIndex(const QString &property, const QString &propertyType); QAbstractListModel *createModel(); void deleteModel(QAbstractListModel *model); + void resetWaitFlags(); private: QProcess *mProcess; - QStringList mNotificationsReceived; + //QStringList mNotificationsReceived; QList<ModelData*> mModels; QString mPluginPath; - QEventLoop mEventLoop2; // for all listmodel slots // Response values + bool mTimedOut; int mItemsCreated; - bool mWaitingForNotification; - bool mWaitingForDataChange; - bool mWaitingForRowsRemoved; - bool mTimeoutCalled; - bool mWaitingForReset; + int mItemsUpdated; + int mItemsRemoved; bool mWaitingForStateChanged; - - bool mTimedOut; - bool callbackError; - bool mCallbackReceived; - QVariant callbackMeta; - QVariant callbackResponse; - + bool mWaitingForRowsInserted; + bool mWaitingForReset; + bool mWaitingForChanged; + bool mWaitingForRemoved; }; #endif diff --git a/tests/auto/jsondblistmodel/jsondblistmodel.pro b/tests/auto/jsondblistmodel/jsondblistmodel.pro index 03be8e62..b4f58d7d 100644 --- a/tests/auto/jsondblistmodel/jsondblistmodel.pro +++ b/tests/auto/jsondblistmodel/jsondblistmodel.pro @@ -1,9 +1,9 @@ TEMPLATE = app TARGET = tst_jsondblistmodel DEPENDPATH += . -INCLUDEPATH += . +INCLUDEPATH += . ../../shared/ -QT = core network testlib gui qml jsondbcompat-private +QT = core network testlib gui qml jsondb CONFIG -= app_bundle CONFIG += testcase @@ -12,5 +12,6 @@ include($$PWD/../../shared/shared.pri) DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\" DEFINES += SRCDIR=\\\"$$PWD/\\\" -HEADERS += testjsondblistmodel.h +HEADERS += testjsondblistmodel.h \ + $$PWD/../../shared/requestwrapper.h SOURCES += testjsondblistmodel.cpp diff --git a/tests/auto/jsondblistmodel/testjsondblistmodel.cpp b/tests/auto/jsondblistmodel/testjsondblistmodel.cpp index d0be9cfd..980b3105 100644 --- a/tests/auto/jsondblistmodel/testjsondblistmodel.cpp +++ b/tests/auto/jsondblistmodel/testjsondblistmodel.cpp @@ -59,6 +59,14 @@ ModelData::~ModelData() delete engine; } +const QString qmlProgram = QLatin1String( + "import QtQuick 2.0\n" + "import QtJsonDb 1.0 as JsonDb\n" + "JsonDb.JsonDbListModel {" + "id: contactsModel;" + "partition: JsonDb.Partition {name: \"com.example.shared.1\"}" + "}"); + QVariant get(QObject* object, int index, QString propertyName) { QVariant retVal; @@ -85,7 +93,6 @@ void listSetProperty(QObject* object, int index, QString propertyName, QVariant } TestJsonDbListModel::TestJsonDbListModel() - : mWaitingForNotification(false), mWaitingForDataChange(false), mWaitingForRowsRemoved(false) { } @@ -125,13 +132,8 @@ void TestJsonDbListModel::initTestCase() QString socketName = QString("testjsondb_%1").arg(getpid()); mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile); - mClient = new JsonDbClient(this); - connect(mClient, SIGNAL(notified(QString,QtAddOn::JsonDb::JsonDbNotification)), - this, SLOT(notified(QString,QtAddOn::JsonDb::JsonDbNotification))); - connect( mClient, SIGNAL(response(int, const QVariant&)), - this, SLOT(response(int, const QVariant&))); - connect( mClient, SIGNAL(error(int, int, const QString&)), - this, SLOT(error(int, int, const QString&))); + connection = new QJsonDbConnection(); + connection->connectToServer(); mPluginPath = findQMLPluginPath("QtJsonDb"); if (mPluginPath.isEmpty()) @@ -141,9 +143,8 @@ void TestJsonDbListModel::initTestCase() QVariantMap item; item.insert("_type", "Partition"); item.insert("name", "com.example.shared.1"); - int id = mClient->create(item); + int id = create(item); waitForResponse1(id); - } QAbstractItemModel *TestJsonDbListModel::createModel() @@ -158,7 +159,7 @@ QAbstractItemModel *TestJsonDbListModel::createModel() return 0; } newModel->component = new QQmlComponent(newModel->engine); - newModel->component->setData("import QtQuick 2.0\nimport QtJsonDb 1.0 as JsonDb \n JsonDb.JsonDbListModel {id: contactsModel; partition: JsonDb.Partition {name: \"com.example.shared.1\"}}", QUrl()); + newModel->component->setData(qmlProgram.toLocal8Bit(), QUrl()); newModel->model = newModel->component->create(); if (newModel->component->isError()) qDebug() << newModel->component->errors(); @@ -188,31 +189,56 @@ void TestJsonDbListModel::cleanupTestCase() deleteDbFiles(); } +void TestJsonDbListModel::timeout() +{ + RequestWrapper::timeout(); + mTimedOut = true; + eventLoop1.quit(); +} + void TestJsonDbListModel::waitForItemsCreated(int items) { + mTimedOut = false; + QTimer timer; + QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); + timer.start(clientTimeout); + elapsedTimer.start(); + mItemsCreated = 0; - while(mItemsCreated != items) - mEventLoop.processEvents(QEventLoop::AllEvents, mClientTimeout); + while (!mTimedOut && mItemsCreated != items) { + mWaitingForRowsInserted = true; + eventLoop1.exec(QEventLoop::AllEvents); + } } void TestJsonDbListModel::waitForExitOrTimeout() { QTimer timer; QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); - QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop, SLOT(quit())); - timer.start(mClientTimeout); - mElapsedTimer.start(); - mEventLoop.exec(QEventLoop::AllEvents); + timer.start(clientTimeout); + elapsedTimer.start(); + eventLoop1.exec(QEventLoop::AllEvents); +} + +void TestJsonDbListModel::resetWaitFlags() +{ + mItemsCreated = 0; + mItemsUpdated = 0; + mItemsRemoved = 0; + mWaitingForRowsInserted = false; + mWaitingForReset = false; + mWaitingForChanged = false; + mWaitingForRemoved = false; } // Create items in the model. void TestJsonDbListModel::createItem() { + resetWaitFlags(); QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); - int id = mClient->create(item, "com.example.shared.1"); - + int id = create(item, "com.example.shared.1"); waitForResponse1(id); QAbstractItemModel *listModel = createModel(); @@ -224,17 +250,21 @@ void TestJsonDbListModel::createItem() // now start it working QCOMPARE(listModel->property("count").toInt(), 0); - + mWaitingForReset = true; waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->property("count").toInt(), 1); item.insert("_type", __FUNCTION__); item.insert("name", "Baker"); mItemsCreated = 0; - id = mClient->create(item, "com.example.shared.1"); + id = create(item, "com.example.shared.1"); waitForResponse1(id); - if (!mItemsCreated) + while (!mItemsCreated) { + mWaitingForRowsInserted = true; waitForExitOrTimeout(); + } + QCOMPARE(mWaitingForRowsInserted, false); QCOMPARE(listModel->property("count").toInt(), 2); deleteModel(listModel); @@ -243,12 +273,12 @@ void TestJsonDbListModel::createItem() // Create an item and then update it. void TestJsonDbListModel::updateItemClient() { + resetWaitFlags(); QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); - int id = mClient->create(item, "com.example.shared.1"); + int id = create(item, "com.example.shared.1"); waitForResponse1(id); - QAbstractItemModel *listModel = createModel(); if (!listModel) return; listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); @@ -258,36 +288,45 @@ void TestJsonDbListModel::updateItemClient() // now start it working QCOMPARE(listModel->property("count").toInt(), 0); - + mWaitingForReset = true; waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->property("count").toInt(), 1); - item.insert("_uuid", mLastUuid); + QString lastUuid,lastVersion; + QVariantMap lastItem; + if (lastResult.count()) { + lastItem = lastResult[0].toMap(); + lastUuid = lastItem.value("_uuid").toString(); + lastVersion = lastItem.value("_version").toString(); + } + item.insert("_uuid", lastUuid); + item.insert("_version", lastVersion); item.insert("name", "Baker"); - - mWaitingForDataChange = true; - id = mClient->update(item, "com.example.shared.1"); + id = update(item, "com.example.shared.1"); waitForResponse1(id); - - while (mWaitingForDataChange) - mEventLoop.processEvents(QEventLoop::AllEvents); + while (!mItemsUpdated) { + mWaitingForChanged = true; + waitForExitOrTimeout(); + } + QCOMPARE(mWaitingForChanged, false); QCOMPARE(listModel->property("count").toInt(), 1); - QCOMPARE(get(listModel, 0, "_uuid").toString(), mLastUuid); + QCOMPARE(get(listModel, 0, "_uuid").toString(), lastUuid); QCOMPARE(get(listModel, 0, "_type").toString(), QLatin1String(__FUNCTION__)); QCOMPARE(get(listModel, 0, "name").toString(), QLatin1String("Baker")); deleteModel(listModel); } - // Create an item and then update it. void TestJsonDbListModel::updateItemSet() { + resetWaitFlags(); QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); item.insert("phone", "123456789"); - int id = mClient->create(item, "com.example.shared.1"); + int id = create(item, "com.example.shared.1"); waitForResponse1(id); QAbstractItemModel *listModel = createModel(); @@ -299,8 +338,9 @@ void TestJsonDbListModel::updateItemSet() // now start it working QCOMPARE(listModel->property("count").toInt(), 0); - + mWaitingForReset = true; waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->property("count").toInt(), 1); QJSEngine engine; @@ -309,12 +349,12 @@ void TestJsonDbListModel::updateItemSet() value.setProperty("name", "Baker"); value.setProperty("phone", "987654321"); - mWaitingForDataChange = true; - set(listModel, 0, value); - - while (mWaitingForDataChange) - mEventLoop.processEvents(QEventLoop::AllEvents); + while (!mItemsUpdated) { + mWaitingForChanged = true; + waitForExitOrTimeout(); + } + QCOMPARE(mWaitingForChanged, false); QCOMPARE(listModel->property("count").toInt(), 1); QCOMPARE(get(listModel, 0, "_type").toString(), QLatin1String(__FUNCTION__)); @@ -322,13 +362,15 @@ void TestJsonDbListModel::updateItemSet() QCOMPARE(get(listModel, 0, "phone").toString(), QLatin1String("987654321")); deleteModel(listModel); } + void TestJsonDbListModel::updateItemSetProperty() { + resetWaitFlags(); QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); item.insert("phone", "123456789"); - int id = mClient->create(item, "com.example.shared.1"); + int id = create(item, "com.example.shared.1"); waitForResponse1(id); QAbstractItemModel *listModel = createModel(); @@ -340,16 +382,17 @@ void TestJsonDbListModel::updateItemSetProperty() // now start it working QCOMPARE(listModel->property("count").toInt(), 0); - + mWaitingForReset = true; waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->property("count").toInt(), 1); - mWaitingForDataChange = true; - listSetProperty(listModel, 0, QString("phone"), QVariant("987654321")); - - while (mWaitingForDataChange) - mEventLoop.processEvents(QEventLoop::AllEvents); + while (!mItemsUpdated) { + mWaitingForChanged = true; + waitForExitOrTimeout(); + } + QCOMPARE(mWaitingForChanged, false); QCOMPARE(listModel->property("count").toInt(), 1); QCOMPARE(get(listModel, 0, "_type").toString(), QLatin1String(__FUNCTION__)); @@ -360,10 +403,11 @@ void TestJsonDbListModel::updateItemSetProperty() void TestJsonDbListModel::deleteItem() { + resetWaitFlags(); QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); - int id = mClient->create(item, "com.example.shared.1"); + int id = create(item, "com.example.shared.1"); waitForResponse1(id); QAbstractItemModel *listModel = createModel(); @@ -374,24 +418,38 @@ void TestJsonDbListModel::deleteItem() connectListModel(listModel); // now start it working + mWaitingForReset = true; waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->property("count").toInt(), 1); item.insert("name", "Baker"); mItemsCreated = 0; - id = mClient->create(item,"com.example.shared.1"); + id = create(item,"com.example.shared.1"); waitForResponse1(id); - if (!mItemsCreated) + while (!mItemsCreated) { + mWaitingForRowsInserted = true; waitForExitOrTimeout(); + } + QCOMPARE(mWaitingForRowsInserted, false); QCOMPARE(listModel->property("count").toInt(), 2); - mWaitingForRowsRemoved = true; - item.insert("_uuid", mLastUuid); - id = mClient->remove(item, "com.example.shared.1"); - + QString lastUuid,lastVersion; + QVariantMap lastItem; + if (lastResult.count()) { + lastItem = lastResult[0].toMap(); + lastUuid = lastItem.value("_uuid").toString(); + lastVersion = lastItem.value("_version").toString(); + } + item.insert("_uuid", lastUuid); + item.insert("_version", lastVersion); + id = remove(item, "com.example.shared.1"); waitForResponse1(id); - while (mWaitingForRowsRemoved) - mEventLoop.processEvents(QEventLoop::AllEvents); + while (!mItemsRemoved) { + mWaitingForRemoved = true; + waitForExitOrTimeout(); + } + QCOMPARE(mWaitingForRemoved, false); QCOMPARE(listModel->property("count").toInt(), 1); QCOMPARE(get(listModel, 0, "_type").toString(), QLatin1String(__FUNCTION__)); @@ -399,9 +457,9 @@ void TestJsonDbListModel::deleteItem() deleteModel(listModel); } - void TestJsonDbListModel::sortedQuery() { + resetWaitFlags(); int id = 0; QVariantMap index; @@ -409,14 +467,14 @@ void TestJsonDbListModel::sortedQuery() index.insert("name", "number"); index.insert("propertyName", "number"); index.insert("propertyType", "number"); - id = mClient->create(index, "com.example.shared.1"); + id = create(index, "com.example.shared.1"); waitForResponse1(id); for (int i = 0; i < 1000; i++) { QVariantMap item; item.insert("_type", "RandNumber"); item.insert("number", i); - id = mClient->create(item, "com.example.shared.1"); + id = create(item, "com.example.shared.1"); waitForResponse1(id); } @@ -430,29 +488,36 @@ void TestJsonDbListModel::sortedQuery() listModel->setProperty("roleNames", rolenames); listModel->setProperty("query", "[?_type=\"RandNumber\"][/number]"); + QCOMPARE(listModel->property("count").toInt(), 0); + mWaitingForReset = true; waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->property("count").toInt(), 1000); + for (int i = 0; i < 1000; i++) QCOMPARE(get(listModel, i,"number").toInt(), i); - listModel->setProperty("query","[?_type=\"RandNumber\"][\\number]"); + mWaitingForReset = true; waitForExitOrTimeout(); - for (int i = 0; i < 1000; i++) + QCOMPARE(mWaitingForReset, false); + QCOMPARE(listModel->property("count").toInt(), 1000); + for (int i = 0; i < 1000; i++) { QCOMPARE(get(listModel, i,"number").toInt(), 999-i); + } QCoreApplication::instance()->processEvents(); deleteModel(listModel); } - void TestJsonDbListModel::ordering() { + resetWaitFlags(); for (int i = 9; i >= 1; --i) { QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); item.insert("order", QString::number(i)); - int id = mClient->create(item, "com.example.shared.1"); + int id = create(item, "com.example.shared.1"); waitForResponse1(id); } @@ -465,13 +530,13 @@ void TestJsonDbListModel::ordering() // now start it working QCOMPARE(listModel->property("count").toInt(), 0); - + mWaitingForReset = true; waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QStringList expectedOrder = QStringList() << "1" << "2" << "3" << "4" << "5" << "6" << "7" << "8" << "9"; QCOMPARE(getOrderValues(listModel), expectedOrder); - mWaitingForDataChange = true; { QVariant uuid = get(listModel, 4, "_uuid"); QVERIFY(!uuid.toString().isEmpty()); @@ -481,17 +546,19 @@ void TestJsonDbListModel::ordering() item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); item.insert("order", "99"); // move it to the end - int id = mClient->update(item, "com.example.shared.1"); + int id = update(item, "com.example.shared.1"); waitForResponse1(id); } - - while (mWaitingForDataChange) - mEventLoop.processEvents(QEventLoop::AllEvents); + while (!mItemsUpdated) { + mWaitingForChanged = true; + waitForExitOrTimeout(); + } + QCOMPARE(mWaitingForChanged, false); expectedOrder = QStringList() << "1" << "2" << "3" << "4" << "6" << "7" << "8" << "9" << "99"; QCOMPARE(getOrderValues(listModel), expectedOrder); - mWaitingForDataChange = true; + mItemsUpdated = 0; { QVariant uuid = get(listModel, 8, "_uuid"); QVERIFY(!uuid.toString().isEmpty()); @@ -501,17 +568,19 @@ void TestJsonDbListModel::ordering() item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); item.insert("order", "22"); // move it after "2" - int id = mClient->update(item, "com.example.shared.1"); + int id = update(item, "com.example.shared.1"); waitForResponse1(id); } - - while (mWaitingForDataChange) - mEventLoop.processEvents(QEventLoop::AllEvents); + while (!mItemsUpdated) { + mWaitingForChanged = true; + waitForExitOrTimeout(); + } + QCOMPARE(mWaitingForChanged, false); expectedOrder = QStringList() << "1" << "2" << "22" << "3" << "4" << "6" << "7" << "8" << "9"; QCOMPARE(getOrderValues(listModel), expectedOrder); - mWaitingForDataChange = true; + mItemsUpdated = 0; { QVariant uuid = get(listModel, 5, "_uuid"); QVERIFY(!uuid.toString().isEmpty()); @@ -521,29 +590,30 @@ void TestJsonDbListModel::ordering() item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); item.insert("order", "0"); // move it to the beginning - int id = mClient->update(item, "com.example.shared.1"); + int id = update(item, "com.example.shared.1"); waitForResponse1(id); } - - while (mWaitingForDataChange) - mEventLoop.processEvents(QEventLoop::AllEvents); + while (!mItemsUpdated) { + mWaitingForChanged = true; + waitForExitOrTimeout(); + } + QCOMPARE(mWaitingForChanged, false); expectedOrder = QStringList() << "0" << "1" << "2" << "22" << "3" << "4" << "7" << "8" << "9"; QCOMPARE(getOrderValues(listModel), expectedOrder); deleteModel(listModel); - } void TestJsonDbListModel::itemNotInCache() { + resetWaitFlags(); QVariantMap index; index.insert("_type", "Index"); index.insert("name", "order"); index.insert("propertyName", "order"); index.insert("propertyType", "number"); - //index.insert("partition", "com.example.shared.1"); - int indexId = mClient->create(index, "com.example.shared.1"); + int indexId = create(index, "com.example.shared.1"); waitForResponse1(indexId); QVariantList itemList; @@ -554,7 +624,7 @@ void TestJsonDbListModel::itemNotInCache() item.insert("order", i); itemList << item; } - int id = mClient->create(itemList, "com.example.shared.1"); + int id = create(itemList, "com.example.shared.1"); waitForResponse1(id); QAbstractItemModel *listModel = createModel(); @@ -564,14 +634,16 @@ void TestJsonDbListModel::itemNotInCache() listModel->setProperty("query", QString("[?_type=\"%1\"][/order]").arg(__FUNCTION__)); QStringList roleNames = (QStringList() << "_type" << "_uuid" << "name" << "order"); listModel->setProperty("roleNames",roleNames); + mWaitingForReset = true; waitForExitOrTimeout(); - + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->property("count").toInt(), 1000); // Make sure that the first items in the list is in the cache. QVariant result = listModel->data(listModel->index(10,0), 3); QVERIFY(result.isValid()); QCOMPARE(result.toInt(), 10); + // This item should not be in the cache now. QVariant res = listModel->data(listModel->index(960,0), 3); QCOMPARE(res.toInt(), 960); @@ -580,11 +652,12 @@ void TestJsonDbListModel::itemNotInCache() void TestJsonDbListModel::roles() { + resetWaitFlags(); QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); item.insert("phone", "123456789"); - int id = mClient->create(item, "com.example.shared.1"); + int id = create(item, "com.example.shared.1"); waitForResponse1(id); @@ -597,7 +670,9 @@ void TestJsonDbListModel::roles() connectListModel(listModel); // now start it working + mWaitingForReset = true; waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->property("count").toInt(), 1); QVariantMap roles = listModel->property("roleNames").toMap(); @@ -609,17 +684,17 @@ void TestJsonDbListModel::roles() void TestJsonDbListModel::totalRowCount() { + resetWaitFlags(); int id = 0; QVariantList insertedItems; for (int i = 0; i < 10; i++) { QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("order", i); - id = mClient->create(item, "com.example.shared.1"); + id = create(item, "com.example.shared.1"); waitForResponse1(id); - insertedItems << mData; + insertedItems << lastResult; } - QAbstractItemModel *listModel = createModel(); if (!listModel) return; @@ -630,14 +705,16 @@ void TestJsonDbListModel::totalRowCount() QStringList roleNames = (QStringList() << "_type" << "_uuid" << "order"); listModel->setProperty("roleNames",roleNames); + mWaitingForReset = true; waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->property("count").toInt(), 10); for (int i = 10; i < 50; i++) { QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("order", i); - mClient->create(item, "com.example.shared.1"); + create(item, "com.example.shared.1"); } waitForItemsCreated(40); @@ -645,15 +722,22 @@ void TestJsonDbListModel::totalRowCount() // Change query listModel->setProperty("query", QString("[?_type=\"%1\"][\\order]").arg(__FUNCTION__)); + mWaitingForReset = true; waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->property("count").toInt(), 50); // Delete the first 10 items foreach (QVariant item, insertedItems) { - mWaitingForRowsRemoved = true; - id = mClient->remove(item.toMap(), "com.example.shared.1"); - while(mWaitingForRowsRemoved) - mEventLoop.processEvents(QEventLoop::AllEvents); + mItemsRemoved = 0; + id = remove(item.toMap(), "com.example.shared.1"); + waitForResponse1(id); + + while (!mTimedOut && !mItemsRemoved) { + mWaitingForRemoved = true; + waitForExitOrTimeout(); + } + QCOMPARE(mWaitingForRemoved, false); } QCOMPARE(listModel->property("count").toInt(), 40); @@ -663,11 +747,13 @@ void TestJsonDbListModel::totalRowCount() void TestJsonDbListModel::listProperty() { + resetWaitFlags(); QVariant jsonData = readJsonFile(findFile("list-objects.json")).toVariant(); QVariantList itemList = jsonData.toList(); + int id = 0; for (int i = 0; i < itemList.count(); i++) { - id = mClient->create(itemList[i].toMap(), "com.example.shared.1"); + id = create(itemList[i].toMap(), "com.example.shared.1"); waitForResponse1(id); } @@ -680,13 +766,23 @@ void TestJsonDbListModel::listProperty() listModel->setProperty("query", QString("[?_type=\"%1\"][/features.0.properties.0.description]").arg(type)); QStringList roleNames = (QStringList() << "_type" << "_uuid" << "features.0.properties.0.description"<< "features.0.feature"); listModel->setProperty("roleNames",roleNames); + mWaitingForReset = true; waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); + + QString lastUuid,lastVersion; + QVariantMap lastItem; + if (lastResult.count()) { + lastItem = lastResult[0].toMap(); + lastUuid = lastItem.value("_uuid").toString(); + lastVersion = lastItem.value("_version").toString(); + } QCOMPARE(listModel->property("count").toInt(), itemList.count()); QCOMPARE(get(listModel, 0, "_type").toString(), type); QCOMPARE(get(listModel, 0, "features.0.properties.0.description").toString(), QLatin1String("Facebook account provider")); QCOMPARE(get(listModel, 0, "features.0.feature").toString(), QLatin1String("provide Facebook")); - QCOMPARE(get(listModel, 1, "_uuid").toString(), mLastUuid); + QCOMPARE(get(listModel, 1, "_uuid").toString(), lastUuid); QCOMPARE(get(listModel, 1, "_type").toString(), type); QCOMPARE(get(listModel, 1, "features.0.properties.0.description").toString(), QLatin1String("Gmail account provider")); QCOMPARE(get(listModel, 1, "features.0.feature").toString(), QLatin1String("provide Gmail")); @@ -703,7 +799,9 @@ void TestJsonDbListModel::listProperty() roleNames.clear(); roleNames = (QStringList() << "_type" << "_uuid" << "features[0].properties[0].description"<< "features[0].supported[0]"); listModel->setProperty("roleNames",roleNames); + mWaitingForReset = true; waitForExitOrTimeout(); + QCOMPARE(mWaitingForReset, false); QCOMPARE(listModel->property("count").toInt(), itemList.count()); QCOMPARE(get(listModel, 0, "_type").toString(), type); @@ -724,18 +822,22 @@ QStringList TestJsonDbListModel::getOrderValues(QAbstractItemModel *listModel) return vals; } - void TestJsonDbListModel::modelReset() { - //qDebug() << "TestJsonDbListModel::modelReset"; - mEventLoop.exit(0); + if (mWaitingForReset) { + mWaitingForReset = false; + eventLoop1.exit(0); + } } void TestJsonDbListModel::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { Q_UNUSED(topLeft); Q_UNUSED(bottomRight); - //qDebug() << "TestJsonDbListModel::dataChanged"; - mWaitingForDataChange = false; + mItemsUpdated++; + if (mWaitingForChanged) { + mWaitingForChanged = false; + eventLoop1.exit(0); + } } void TestJsonDbListModel::rowsInserted(const QModelIndex &parent, int first, int last) { @@ -743,16 +845,21 @@ void TestJsonDbListModel::rowsInserted(const QModelIndex &parent, int first, int Q_UNUSED(first); Q_UNUSED(last); mItemsCreated++; - //qDebug() << "TestJsonDbListModel::rowsInserted"; - mEventLoop.exit(0); + if (mWaitingForRowsInserted) { + mWaitingForRowsInserted = false; + eventLoop1.exit(0); + } } void TestJsonDbListModel::rowsRemoved(const QModelIndex &parent, int first, int last) { Q_UNUSED(parent); Q_UNUSED(first); Q_UNUSED(last); - mWaitingForRowsRemoved = false; - //qDebug() << "TestJsonDbListModel::rowsRemoved"; + mItemsRemoved++; + if (mWaitingForRemoved) { + mWaitingForRemoved = false; + eventLoop1.exit(0); + } } void TestJsonDbListModel::rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row ) { @@ -761,7 +868,6 @@ void TestJsonDbListModel::rowsMoved( const QModelIndex &parent, int start, int e Q_UNUSED(end); Q_UNUSED(destination); Q_UNUSED(row); - //qDebug() << "TestJsonDbListModel::rowsMoved"; } QTEST_MAIN(TestJsonDbListModel) diff --git a/tests/auto/jsondblistmodel/testjsondblistmodel.h b/tests/auto/jsondblistmodel/testjsondblistmodel.h index 36fbf332..8be75759 100644 --- a/tests/auto/jsondblistmodel/testjsondblistmodel.h +++ b/tests/auto/jsondblistmodel/testjsondblistmodel.h @@ -41,22 +41,9 @@ #ifndef TestJsonDbListModel_H #define TestJsonDbListModel_H -#include <QCoreApplication> -#include <QList> -#include <QTest> -#include <QFile> -#include <QProcess> -#include <QEventLoop> -#include <QDebug> -#include <QLocalSocket> -#include <QTimer> - -#include <jsondb-client.h> -#include <jsondb-error.h> - #include <QAbstractItemModel> -#include "clientwrapper.h" -#include "../../shared/qmltestutil.h" +#include "requestwrapper.h" +#include "qmltestutil.h" QT_BEGIN_NAMESPACE class QQmlEngine; @@ -76,7 +63,7 @@ public: QObject *model; }; -class TestJsonDbListModel: public ClientWrapper +class TestJsonDbListModel: public RequestWrapper { Q_OBJECT public: @@ -108,25 +95,30 @@ private slots: void roles(); void totalRowCount(); void listProperty(); - +public: + void timeout(); private: void waitForExitOrTimeout(); void waitForItemsCreated(int items); QStringList getOrderValues(QAbstractItemModel *listModel); QAbstractItemModel *createModel(); void deleteModel(QAbstractItemModel *model); + void resetWaitFlags(); private: - QProcess *mProcess; - QStringList mNotificationsReceived; + QProcess *mProcess; QList<ModelData*> mModels; QString mPluginPath; // Response values - int mItemsCreated; - bool mWaitingForNotification; - bool mWaitingForDataChange; - bool mWaitingForRowsRemoved; + bool mTimedOut; + int mItemsCreated; + int mItemsUpdated; + int mItemsRemoved; + bool mWaitingForRowsInserted; + bool mWaitingForReset; + bool mWaitingForChanged; + bool mWaitingForRemoved; }; #endif diff --git a/tests/auto/jsondbnotification/jsondbnotification.pro b/tests/auto/jsondbnotification/jsondbnotification.pro index 824ba10c..b02e97a1 100644 --- a/tests/auto/jsondbnotification/jsondbnotification.pro +++ b/tests/auto/jsondbnotification/jsondbnotification.pro @@ -1,9 +1,9 @@ TEMPLATE = app TARGET = tst_jsondbnotification DEPENDPATH += . -INCLUDEPATH += . +INCLUDEPATH += . ../../shared/ -QT = core network testlib gui qml jsondbcompat-private +QT = core network testlib gui qml jsondb CONFIG -= app_bundle CONFIG += testcase @@ -12,5 +12,6 @@ include($$PWD/../../shared/shared.pri) DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\" DEFINES += SRCDIR=\\\"$$PWD/\\\" -HEADERS += testjsondbnotification.h +HEADERS += testjsondbnotification.h \ + $$PWD/../../shared/requestwrapper.h SOURCES += testjsondbnotification.cpp diff --git a/tests/auto/jsondbnotification/testjsondbnotification.cpp b/tests/auto/jsondbnotification/testjsondbnotification.cpp index 9589e534..6468046a 100644 --- a/tests/auto/jsondbnotification/testjsondbnotification.cpp +++ b/tests/auto/jsondbnotification/testjsondbnotification.cpp @@ -70,7 +70,6 @@ const QString qmlProgramForPartition = QLatin1String( "name: \"com.nokia.shared\";" "}"); - TestJsonDbNotification::TestJsonDbNotification() : mTimedOut(false) { @@ -83,8 +82,9 @@ TestJsonDbNotification::~TestJsonDbNotification() void TestJsonDbNotification::timeout() { - ClientWrapper::timeout(); + RequestWrapper::timeout(); mTimedOut = true; + eventLoop1.quit(); } void TestJsonDbNotification::deleteDbFiles() @@ -109,23 +109,19 @@ void TestJsonDbNotification::initTestCase() QString socketName = QString("testjsondb_%1").arg(getpid()); mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile); - mClient = new JsonDbClient(this); - connect(mClient, SIGNAL(notified(QString,QtAddOn::JsonDb::JsonDbNotification)), - this, SLOT(notified(QString,QtAddOn::JsonDb::JsonDbNotification))); - connect( mClient, SIGNAL(response(int, const QVariant&)), - this, SLOT(response(int, const QVariant&))); - connect( mClient, SIGNAL(error(int, int, const QString&)), - this, SLOT(error(int, int, const QString&))); + connection = new QJsonDbConnection(); + connection->connectToServer(); mPluginPath = findQMLPluginPath("QtJsonDb"); + if (mPluginPath.isEmpty()) + qDebug() << "Couldn't find the plugin path for the plugin QtJsonDb"; // Create the shared Partitions QVariantMap item; item.insert("_type", "Partition"); item.insert("name", "com.nokia.shared"); - int id = mClient->create(item); + int id = create(item); waitForResponse1(id); - } ComponentData *TestJsonDbNotification::createComponent() @@ -145,6 +141,8 @@ ComponentData *TestJsonDbNotification::createComponent() qDebug() << componentData->component->errors(); QObject::connect(componentData->qmlElement, SIGNAL(notificationSignal(QVariant, int, int)), this, SLOT(notificationSlot(QVariant, int, int))); + QObject::connect(componentData->qmlElement, SIGNAL(statusChanged(JsonDbNotify::Status)), + this, SLOT(statusChangedSlot2())); mComponents.append(componentData); return componentData; } @@ -192,8 +190,8 @@ void TestJsonDbNotification::notificationSlot(QVariant result, int action, int s data.result = result.toMap(); data.action = action; data.stateNumber = stateNumber; - cbData.append(data); - mEventLoop2.quit(); + callbackData.append(data); + eventLoop1.quit(); } void TestJsonDbNotification::errorSlot(int code, const QString &message) @@ -201,7 +199,7 @@ void TestJsonDbNotification::errorSlot(int code, const QString &message) callbackError = true; callbackErrorCode = code; callbackErrorMessage = message; - mEventLoop2.quit(); + eventLoop1.quit(); } void TestJsonDbNotification::notificationSlot2(QJSValue result, Actions action, int stateNumber) @@ -210,8 +208,13 @@ void TestJsonDbNotification::notificationSlot2(QJSValue result, Actions action, data.result = result.toVariant().toMap(); data.action = action; data.stateNumber = stateNumber; - cbData.append(data); - mEventLoop2.quit(); + callbackData.append(data); + eventLoop1.quit(); +} + +void TestJsonDbNotification::statusChangedSlot2() +{ + eventLoop1.quit(); } void TestJsonDbNotification::singleObjectNotifications() @@ -226,31 +229,36 @@ void TestJsonDbNotification::singleObjectNotifications() actionsList.append(2); actionsList.append(4); notification->qmlElement->setProperty("actions", actionsList); + // Wait for Ready Status + int status = 0; + while ((status = notification->qmlElement->property("status").toInt()) < 2) { + waitForCallback1(); + } CallbackData data; //Create an object QVariantMap item = createObject(__FUNCTION__).toMap(); - mClient->create(item, "com.nokia.shared"); - waitForCallback2(); - QCOMPARE(cbData.size(), 1); - data = cbData.takeAt(0); + create(item, "com.nokia.shared"); + waitForCallback1(); + QCOMPARE(callbackData.size(), 1); + data = callbackData.takeAt(0); QCOMPARE(data.action, 1); QCOMPARE(data.result.value("alphabet"), item.value("alphabet")); QString uuid = data.result.value("_uuid").toString(); //update the object QString newAlphabet = data.result.value("alphabet").toString()+QString("**"); data.result.insert("alphabet", newAlphabet); - mClient->update(data.result, "com.nokia.shared"); - waitForCallback2(); - QCOMPARE(cbData.size(), 1); - data = cbData.takeAt(0); + update(data.result, "com.nokia.shared"); + waitForCallback1(); + QCOMPARE(callbackData.size(), 1); + data = callbackData.takeAt(0); QCOMPARE(data.action, 2); QCOMPARE(data.result.value("alphabet").toString(), newAlphabet); //Remove the object - mClient->remove(data.result, "com.nokia.shared"); - waitForCallback2(); - QCOMPARE(cbData.size(), 1); - data = cbData.takeAt(0); + remove(data.result, "com.nokia.shared"); + waitForCallback1(); + QCOMPARE(callbackData.size(), 1); + data = callbackData.takeAt(0); QCOMPARE(data.action, 4); QCOMPARE(data.result.value("_uuid").toString(), uuid); deleteComponent(notification); @@ -268,65 +276,70 @@ void TestJsonDbNotification::multipleObjectNotifications() actionsList.append(2); actionsList.append(4); notification->qmlElement->setProperty("actions", actionsList); + // Wait for Ready Status + int status = 0; + while ((status = notification->qmlElement->property("status").toInt()) < 2) { + waitForCallback1(); + } //Create objects QVariantList items = createObjectList(__FUNCTION__, 10).toList(); - mClient->create(QVariant(items), "com.nokia.shared"); + create(items, "com.nokia.shared"); for (int i = 0; i<10; i++) { - waitForCallback2(); - if (cbData.size() >= 10) + waitForCallback1(); + if (callbackData.size() >= 10) break; } - QCOMPARE(cbData.size(), 10); + QCOMPARE(callbackData.size(), 10); QVariantList objList; for (int i = 0; i<10; i++) { - QCOMPARE(cbData[i].action, 1); + QCOMPARE(callbackData[i].action, 1); QVariantMap item = items[i].toMap(); - QVariantMap obj = cbData[i].result; + QVariantMap obj = callbackData[i].result; QCOMPARE(obj.value("alphabet"), item.value("alphabet")); - QString newAlphabet = cbData[i].result.value("alphabet").toString()+QString("**"); + QString newAlphabet = callbackData[i].result.value("alphabet").toString()+QString("**"); obj.insert("alphabet", newAlphabet); objList.append(obj); } - cbData.clear(); + callbackData.clear(); //update the object - mClient->update(QVariant(objList), "com.nokia.shared"); + update(objList, "com.nokia.shared"); for (int i = 0; i<10; i++) { - waitForCallback2(); - if (cbData.size() >= 10) + waitForCallback1(); + if (callbackData.size() >= 10) break; } - QCOMPARE(cbData.size(), 10); + QCOMPARE(callbackData.size(), 10); QVariantList lst = objList; objList.clear(); for (int i = 0; i<10; i++) { - QCOMPARE(cbData[i].action, 2); + QCOMPARE(callbackData[i].action, 2); QVariantMap item = lst[i].toMap(); - QVariantMap obj = cbData[i].result; + QVariantMap obj = callbackData[i].result; QCOMPARE(obj.value("alphabet"), item.value("alphabet")); objList.append(obj); } - cbData.clear(); + callbackData.clear(); //Remove the object - mClient->remove(objList, "com.nokia.shared"); + remove(objList, "com.nokia.shared"); for (int i = 0; i<10; i++) { - waitForCallback2(); - if (cbData.size() >= 10) + waitForCallback1(); + if (callbackData.size() >= 10) break; } - QCOMPARE(cbData.size(), 10); + QCOMPARE(callbackData.size(), 10); for (int i = 0; i<10; i++) { - QCOMPARE(cbData[i].action, 4); + QCOMPARE(callbackData[i].action, 4); QVariantMap item = objList[i].toMap(); - QVariantMap obj = cbData[i].result; + QVariantMap obj = callbackData[i].result; QCOMPARE(obj.value("_uuid"), item.value("_uuid")); } - cbData.clear(); + callbackData.clear(); deleteComponent(notification); } - +/* void TestJsonDbNotification::createNotification() { const QString createString = QString("createNotification('[?_type=\"%1\"]');"); @@ -340,21 +353,30 @@ void TestJsonDbNotification::createNotification() QPointer<QObject> notification = expr->evaluate().value<QObject*>(); QVERIFY(!notification.isNull()); notification->setParent(partition->qmlElement); - QObject::connect(notification, SIGNAL(notification(QJSValue, Actions, int)), - this, SLOT(notificationSlot2(QJSValue, Actions, int))); + QObject::connect(notification, SIGNAL(notification(QJSValue,Actions,int)), + this, SLOT(notificationSlot2(QJSValue,Actions,int))); + QObject::connect(notification, SIGNAL(statusChanged(JsonDbNotify::Status)), + this, SLOT(statusChangedSlot2())); + // Wait for Ready Status + int status = 0; + while ((status = notification->property("status").toInt()) < 2) { + waitForCallback1(); + } + + CallbackData data; //Create an object QVariantMap item = createObject(__FUNCTION__).toMap(); - mClient->create(item, "com.nokia.shared"); - waitForCallback2(); - QCOMPARE(cbData.size(), 1); - data = cbData.takeAt(0); + create(item, "com.nokia.shared"); + waitForCallback1(); + QCOMPARE(callbackData.size(), 1); + data = callbackData.takeAt(0); QCOMPARE(data.action, 1); QCOMPARE(data.result.value("alphabet"), item.value("alphabet")); delete expr; deleteComponent(partition); } - +*/ QTEST_MAIN(TestJsonDbNotification) diff --git a/tests/auto/jsondbnotification/testjsondbnotification.h b/tests/auto/jsondbnotification/testjsondbnotification.h index 9b728a61..3564ea53 100644 --- a/tests/auto/jsondbnotification/testjsondbnotification.h +++ b/tests/auto/jsondbnotification/testjsondbnotification.h @@ -41,23 +41,9 @@ #ifndef TESTJSONDBNOTIFICATION_H #define TESTJSONDBNOTIFICATION_H -#include <QCoreApplication> -#include <QList> -#include <QTest> -#include <QFile> -#include <QProcess> -#include <QEventLoop> -#include <QDebug> -#include <QLocalSocket> -#include <QTimer> -#include <QJSValue> - -#include <jsondb-client.h> -#include <jsondb-error.h> - #include <QAbstractItemModel> -#include "clientwrapper.h" -#include "../../shared/qmltestutil.h" +#include "requestwrapper.h" +#include "qmltestutil.h" QT_USE_NAMESPACE_JSONDB @@ -67,7 +53,7 @@ struct CallbackData { QVariantMap result; }; -class TestJsonDbNotification: public ClientWrapper +class TestJsonDbNotification: public RequestWrapper { Q_OBJECT public: @@ -85,14 +71,15 @@ private slots: void singleObjectNotifications(); void multipleObjectNotifications(); - void createNotification(); +// void createNotification(); public slots: void notificationSlot(QVariant result, int action, int stateNumber); void errorSlot(int code, const QString &message); void notificationSlot2(QJSValue result, Actions action, int stateNumber); + void statusChangedSlot2(); -protected slots: +public: void timeout(); private: @@ -105,12 +92,10 @@ private: QStringList mNotificationsReceived; QList<ComponentData*> mComponents; QString mPluginPath; + + // Response values bool mTimedOut; - bool callbackError; - int callbackErrorCode; - QString callbackErrorMessage; - QList<CallbackData> cbData; - QEventLoop mEventLoop2; + QList<CallbackData> callbackData; }; #endif diff --git a/tests/auto/jsondbpartition/jsondbpartition.pro b/tests/auto/jsondbpartition/jsondbpartition.pro index 1724f364..b588b0f2 100644 --- a/tests/auto/jsondbpartition/jsondbpartition.pro +++ b/tests/auto/jsondbpartition/jsondbpartition.pro @@ -1,9 +1,9 @@ TEMPLATE = app TARGET = tst_jsondbpartition DEPENDPATH += . -INCLUDEPATH += . +INCLUDEPATH += . ../../shared/ -QT = core network testlib gui qml jsondbcompat-private +QT = core network testlib gui qml jsondb CONFIG -= app_bundle CONFIG += testcase @@ -12,5 +12,6 @@ include($$PWD/../../shared/shared.pri) DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\" DEFINES += SRCDIR=\\\"$$PWD/\\\" -HEADERS += testjsondbpartition.h +HEADERS += testjsondbpartition.h \ + $$PWD/../../shared/requestwrapper.h SOURCES += testjsondbpartition.cpp diff --git a/tests/auto/jsondbpartition/testjsondbpartition.cpp b/tests/auto/jsondbpartition/testjsondbpartition.cpp index bf6a0b53..018c698a 100644 --- a/tests/auto/jsondbpartition/testjsondbpartition.cpp +++ b/tests/auto/jsondbpartition/testjsondbpartition.cpp @@ -68,8 +68,9 @@ TestJsonDbPartition::~TestJsonDbPartition() void TestJsonDbPartition::timeout() { - ClientWrapper::timeout(); + RequestWrapper::timeout(); mTimedOut = true; + eventLoop1.quit(); } void TestJsonDbPartition::deleteDbFiles() @@ -94,23 +95,19 @@ void TestJsonDbPartition::initTestCase() QString socketName = QString("testjsondb_%1").arg(getpid()); mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile); - mClient = new JsonDbClient(this); - connect(mClient, SIGNAL(notified(QString,QtAddOn::JsonDb::JsonDbNotification)), - this, SLOT(notified(QString,QtAddOn::JsonDb::JsonDbNotification))); - connect( mClient, SIGNAL(response(int, const QVariant&)), - this, SLOT(response(int, const QVariant&))); - connect( mClient, SIGNAL(error(int, int, const QString&)), - this, SLOT(error(int, int, const QString&))); + connection = new QJsonDbConnection(); + connection->connectToServer(); mPluginPath = findQMLPluginPath("QtJsonDb"); + if (mPluginPath.isEmpty()) + qDebug() << "Couldn't find the plugin path for the plugin QtJsonDb"; // Create the shared Partitions QVariantMap item; item.insert("_type", "Partition"); item.insert("name", "com.nokia.shared.1"); - int id = mClient->create(item); + int id = RequestWrapper::create(item); waitForResponse1(id); - } ComponentData *TestJsonDbPartition::createComponent() @@ -158,7 +155,7 @@ void TestJsonDbPartition::callbackSlot(QVariant error, QVariant response) callbackError = error.isValid(); callbackMeta = response; callbackResponse = response.toMap().value("items").toList(); - mEventLoop.quit(); + eventLoop1.quit(); } // JsonDb.Partition.create() @@ -177,7 +174,7 @@ void TestJsonDbPartition::create() int id = 0; expr = new QQmlExpression(partition->engine->rootContext(), partition->qmlElement, expression); id = expr->evaluate().toInt(); - waitForCallback(); + waitForCallback1(); QCOMPARE(callbackError, false); QCOMPARE(callbackMeta.toMap()["id"].toInt(), id); QCOMPARE(callbackResponse.toList().size(), 1); @@ -186,7 +183,7 @@ void TestJsonDbPartition::create() expression = QString(createString).arg(objectString(QString(), obj)); expr->setExpression(expression); id = expr->evaluate().toInt(); - waitForCallback(); + waitForCallback1(); QCOMPARE(callbackError, false); QCOMPARE(callbackMeta.toMap()["id"].toInt(), id); QCOMPARE(callbackResponse.toList().size(), 1); @@ -195,7 +192,7 @@ void TestJsonDbPartition::create() expression = QString(createString).arg(objectString(QString(), obj)); expr->setExpression(expression); id = expr->evaluate().toInt(); - waitForCallback(); + waitForCallback1(); QCOMPARE(callbackError, false); QCOMPARE(callbackMeta.toMap()["id"].toInt(), id); QCOMPARE(callbackResponse.toList().size(), 5); @@ -223,7 +220,7 @@ void TestJsonDbPartition::update() int id = 0; expr = new QQmlExpression(partition->engine->rootContext(), partition->qmlElement, expression); id = expr->evaluate().toInt(); - waitForCallback(); + waitForCallback1(); QCOMPARE(callbackError, false); QCOMPARE(callbackMeta.toMap()["id"].toInt(), id); QCOMPARE(callbackResponse.toList().size(), 1); @@ -235,7 +232,7 @@ void TestJsonDbPartition::update() expression = QString(updateString).arg(objectString(QString(), obj)); expr->setExpression(expression); id = expr->evaluate().toInt(); - waitForCallback(); + waitForCallback1(); QCOMPARE(callbackError, false); QCOMPARE(callbackMeta.toMap()["id"].toInt(), id); QCOMPARE(callbackResponse.toList().size(), 1); @@ -244,7 +241,7 @@ void TestJsonDbPartition::update() expression = QString(createString).arg(objectString(QString(), obj)); expr->setExpression(expression); id = expr->evaluate().toInt(); - waitForCallback(); + waitForCallback1(); QCOMPARE(callbackError, false); QCOMPARE(callbackMeta.toMap()["id"].toInt(), id); QCOMPARE(callbackResponse.toList().size(), 5); @@ -260,7 +257,7 @@ void TestJsonDbPartition::update() expression = QString(updateString).arg(objectString(QString(), obj)); expr->setExpression(expression); id = expr->evaluate().toInt(); - waitForCallback(); + waitForCallback1(); QCOMPARE(callbackError, false); QCOMPARE(callbackMeta.toMap()["id"].toInt(), id); QCOMPARE(callbackResponse.toList().size(), 5); @@ -288,17 +285,26 @@ void TestJsonDbPartition::remove() int id = 0; expr = new QQmlExpression(partition->engine->rootContext(), partition->qmlElement, expression); id = expr->evaluate().toInt(); - waitForCallback(); + waitForCallback1(); QCOMPARE(callbackError, false); QCOMPARE(callbackMeta.toMap()["id"].toInt(), id); QCOMPARE(callbackResponse.toList().size(), 1); //Remove this object - obj = callbackResponse.toList(); + { + QVariantList newList; + QVariantList list = callbackResponse.toList(); + for (int i = 0; i<list.count(); i++) { + QVariantMap objMap = list[i].toMap(); + objMap.insert("_type", __FUNCTION__); + newList.append(objMap); + } + obj = newList; + } expression = QString(removeString).arg(objectString(QString(), obj)); expr->setExpression(expression); id = expr->evaluate().toInt(); - waitForCallback(); + waitForCallback1(); QCOMPARE(callbackError, false); QCOMPARE(callbackMeta.toMap()["id"].toInt(), id); QCOMPARE(callbackResponse.toList().size(), 1); @@ -307,17 +313,26 @@ void TestJsonDbPartition::remove() expression = QString(createString).arg(objectString(QString(), obj)); expr->setExpression(expression); id = expr->evaluate().toInt(); - waitForCallback(); + waitForCallback1(); QCOMPARE(callbackError, false); QCOMPARE(callbackMeta.toMap()["id"].toInt(), id); QCOMPARE(callbackResponse.toList().size(), 5); //Remove all objects - obj = callbackResponse.toList(); + { + QVariantList newList; + QVariantList list = callbackResponse.toList(); + for (int i = 0; i<list.count(); i++) { + QVariantMap objMap = list[i].toMap(); + objMap.insert("_type", __FUNCTION__); + newList.append(objMap); + } + obj = newList; + } expression = QString(removeString).arg(objectString(QString(), obj)); expr->setExpression(expression); id = expr->evaluate().toInt(); - waitForCallback(); + waitForCallback1(); QCOMPARE(callbackError, false); QCOMPARE(callbackMeta.toMap()["id"].toInt(), id); QCOMPARE(callbackResponse.toList().size(), 5); @@ -344,7 +359,7 @@ void TestJsonDbPartition::find() int id = 0; expr = new QQmlExpression(partition->engine->rootContext(), partition->qmlElement, expression); id = expr->evaluate().toInt(); - waitForCallback(); + waitForCallback1(); QCOMPARE(callbackError, false); QCOMPARE(callbackMeta.toMap()["id"].toInt(), id); QCOMPARE(callbackResponse.toList().size(), 1); @@ -353,7 +368,7 @@ void TestJsonDbPartition::find() expression = findString; expr->setExpression(expression); id = expr->evaluate().toInt(); - waitForCallback(); + waitForCallback1(); QCOMPARE(callbackError, false); QCOMPARE(callbackMeta.toMap()["id"].toInt(), id); QCOMPARE(callbackResponse.toList().size(), 1); @@ -362,7 +377,7 @@ void TestJsonDbPartition::find() expression = QString(createString).arg(objectString(QString(), obj)); expr->setExpression(expression); id = expr->evaluate().toInt(); - waitForCallback(); + waitForCallback1(); QCOMPARE(callbackError, false); QCOMPARE(callbackMeta.toMap()["id"].toInt(), id); QCOMPARE(callbackResponse.toList().size(), 5); @@ -371,7 +386,7 @@ void TestJsonDbPartition::find() expression = findString; expr->setExpression(expression); id = expr->evaluate().toInt(); - waitForCallback(); + waitForCallback1(); QCOMPARE(callbackError, false); QCOMPARE(callbackMeta.toMap()["id"].toInt(), id); QCOMPARE(callbackResponse.toList().size(), 6); diff --git a/tests/auto/jsondbpartition/testjsondbpartition.h b/tests/auto/jsondbpartition/testjsondbpartition.h index f8635389..5ab757bf 100644 --- a/tests/auto/jsondbpartition/testjsondbpartition.h +++ b/tests/auto/jsondbpartition/testjsondbpartition.h @@ -41,26 +41,13 @@ #ifndef TESTJSONDBPARTITION_H #define TESTJSONDBPARTITION_H -#include <QCoreApplication> -#include <QList> -#include <QTest> -#include <QFile> -#include <QProcess> -#include <QEventLoop> -#include <QDebug> -#include <QLocalSocket> -#include <QTimer> - -#include <jsondb-client.h> -#include <jsondb-error.h> - #include <QAbstractItemModel> -#include "clientwrapper.h" -#include "../../shared/qmltestutil.h" +#include "requestwrapper.h" +#include "qmltestutil.h" QT_USE_NAMESPACE_JSONDB -class TestJsonDbPartition: public ClientWrapper +class TestJsonDbPartition: public RequestWrapper { Q_OBJECT public: @@ -80,7 +67,7 @@ private slots: public slots: void callbackSlot(QVariant error, QVariant response); -protected slots: +public: void timeout(); private: @@ -92,10 +79,9 @@ private: QStringList mNotificationsReceived; QList<ComponentData*> mComponents; QString mPluginPath; + + // Response values bool mTimedOut; - bool callbackError; - QVariant callbackMeta; - QVariant callbackResponse; }; #endif diff --git a/tests/auto/jsondbqueryobject/jsondbqueryobject.pro b/tests/auto/jsondbqueryobject/jsondbqueryobject.pro index 0e3daeaf..3b19ea1e 100644 --- a/tests/auto/jsondbqueryobject/jsondbqueryobject.pro +++ b/tests/auto/jsondbqueryobject/jsondbqueryobject.pro @@ -1,9 +1,9 @@ TEMPLATE = app TARGET = tst_jsondbqueryobject DEPENDPATH += . -INCLUDEPATH += . +INCLUDEPATH += . ../../shared/ -QT = core network testlib gui qml jsondbcompat-private +QT = core network testlib gui qml jsondb CONFIG -= app_bundle CONFIG += testcase @@ -12,5 +12,6 @@ include($$PWD/../../shared/shared.pri) DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\" DEFINES += SRCDIR=\\\"$$PWD/\\\" -HEADERS += testjsondbqueryobject.h +HEADERS += testjsondbqueryobject.h \ + $$PWD/../../shared/requestwrapper.h SOURCES += testjsondbqueryobject.cpp diff --git a/tests/auto/jsondbqueryobject/testjsondbqueryobject.cpp b/tests/auto/jsondbqueryobject/testjsondbqueryobject.cpp index 071e2d72..59a49aea 100644 --- a/tests/auto/jsondbqueryobject/testjsondbqueryobject.cpp +++ b/tests/auto/jsondbqueryobject/testjsondbqueryobject.cpp @@ -85,8 +85,9 @@ TestJsonDbQueryObject::~TestJsonDbQueryObject() void TestJsonDbQueryObject::timeout() { - ClientWrapper::timeout(); + RequestWrapper::timeout(); mTimedOut = true; + eventLoop1.quit(); } void TestJsonDbQueryObject::deleteDbFiles() @@ -111,23 +112,19 @@ void TestJsonDbQueryObject::initTestCase() QString socketName = QString("testjsondb_%1").arg(getpid()); mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile); - mClient = new JsonDbClient(this); - connect(mClient, SIGNAL(notified(QString,QtAddOn::JsonDb::JsonDbNotification)), - this, SLOT(notified(QString,QtAddOn::JsonDb::JsonDbNotification))); - connect( mClient, SIGNAL(response(int, const QVariant&)), - this, SLOT(response(int, const QVariant&))); - connect( mClient, SIGNAL(error(int, int, const QString&)), - this, SLOT(error(int, int, const QString&))); + connection = new QJsonDbConnection(); + connection->connectToServer(); mPluginPath = findQMLPluginPath("QtJsonDb"); + if (mPluginPath.isEmpty()) + qDebug() << "Couldn't find the plugin path for the plugin QtJsonDb"; // Create the shared Partitions QVariantMap item; item.insert("_type", "Partition"); item.insert("name", "com.nokia.shared"); - int id = mClient->create(item); + int id = create(item); waitForResponse1(id); - } ComponentData *TestJsonDbQueryObject::createComponent(const QString &qml) @@ -200,14 +197,14 @@ void TestJsonDbQueryObject::errorSlot(const QVariantMap &newError) callbackError = true; callbackErrorCode = code; callbackErrorMessage = message; - mEventLoop2.quit(); + eventLoop1.quit(); } void TestJsonDbQueryObject::finishedSlot() { QMetaObject::invokeMethod(currentQmlElement, "takeResults", Qt::DirectConnection, - Q_RETURN_ARG(QVariantList, cbData)); - mEventLoop2.quit(); + Q_RETURN_ARG(QVariantList, callbackData)); + eventLoop1.quit(); } bool posLessThan(const QVariant &v1, const QVariant &v2) @@ -229,13 +226,14 @@ void TestJsonDbQueryObject::singleObject() //Create an object QVariantMap item = createObject(__FUNCTION__).toMap(); - mClient->create(item, "com.nokia.shared"); + create(item, "com.nokia.shared"); const QString expression("start();"); QQmlExpression *expr; expr = new QQmlExpression(queryObject->engine->rootContext(), queryObject->qmlElement, expression); expr->evaluate(); - waitForCallback2(); - QCOMPARE(cbData.size(), 1); + callbackData.clear(); + waitForCallback1(); + QCOMPARE(callbackData.size(), 1); QCOMPARE(callbackError, false); delete expr; deleteComponent(queryObject); @@ -251,7 +249,8 @@ void TestJsonDbQueryObject::multipleObjects() index.insert("_type", "Index"); index.insert("propertyName", "pos"); index.insert("propertyType", "number"); - mClient->create(index, "com.nokia.shared"); + int id = create(index, "com.nokia.shared"); + waitForResponse1(id); const QString queryString = QString("[?_type = \""+QString( __FUNCTION__ )+"\"][/pos]"); queryObject->qmlElement->setProperty("query", queryString); @@ -259,18 +258,19 @@ void TestJsonDbQueryObject::multipleObjects() //Create objects QVariantList items = createObjectList(__FUNCTION__, 10).toList(); - mClient->create(QVariant(items), "com.nokia.shared"); + create(items, "com.nokia.shared"); qSort(items.begin(), items.end(), posLessThan); const QString expression("start();"); QQmlExpression *expr; expr = new QQmlExpression(queryObject->engine->rootContext(), queryObject->qmlElement, expression); expr->evaluate(); - waitForCallback2(); + callbackData.clear(); + waitForCallback1(); QCOMPARE(callbackError, false); - QCOMPARE(cbData.size(), 10); + QCOMPARE(callbackData.size(), 10); for (int i = 0; i<10; i++) { QVariantMap item = items[i].toMap(); - QVariantMap obj = cbData[i].toMap(); + QVariantMap obj = callbackData[i].toMap(); QCOMPARE(obj.value("alphabet"), item.value("alphabet")); } @@ -298,11 +298,13 @@ void TestJsonDbQueryObject::createQuery() this, SLOT(errorSlot(QVariantMap))); //Create an object QVariantMap item = createObject(__FUNCTION__).toMap(); - mClient->create(item, "com.nokia.shared"); + int id = create(item, "com.nokia.shared"); + waitForResponse1(id); + QMetaObject::invokeMethod(currentQmlElement, "start", Qt::DirectConnection); - cbData.clear(); - waitForCallback2(); - QCOMPARE(cbData.size(), 1); + callbackData.clear(); + waitForCallback1(); + QCOMPARE(callbackData.size(), 1); QCOMPARE(callbackError, false); delete expr; deleteComponent(partition); @@ -318,7 +320,8 @@ void TestJsonDbQueryObject::queryWithoutPartition() index.insert("_type", "Index"); index.insert("propertyName", "pos"); index.insert("propertyType", "number"); - mClient->create(index); + int id = create(index); + waitForResponse1(id); const QString queryString = QString("[?_type = \""+QString( __FUNCTION__ )+"\"][/pos]"); queryObject->qmlElement->setProperty("query", queryString); @@ -326,18 +329,19 @@ void TestJsonDbQueryObject::queryWithoutPartition() //Create objects QVariantList items = createObjectList(__FUNCTION__, 10).toList(); - mClient->create(QVariant(items)); + create(items); qSort(items.begin(), items.end(), posLessThan); const QString expression("start();"); QQmlExpression *expr; expr = new QQmlExpression(queryObject->engine->rootContext(), queryObject->qmlElement, expression); expr->evaluate(); - waitForCallback2(); + callbackData.clear(); + waitForCallback1(); QCOMPARE(callbackError, false); - QCOMPARE(cbData.size(), 10); + QCOMPARE(callbackData.size(), 10); for (int i = 0; i<10; i++) { QVariantMap item = items[i].toMap(); - QVariantMap obj = cbData[i].toMap(); + QVariantMap obj = callbackData[i].toMap(); QCOMPARE(obj.value("alphabet"), item.value("alphabet")); } @@ -360,19 +364,20 @@ void TestJsonDbQueryObject::queryBinding() queryObject->qmlElement->setProperty("bindings", bindingMap); currentQmlElement = queryObject->qmlElement; - mClient->create(QVariant(items), "com.nokia.shared"); + create(items, "com.nokia.shared"); qSort(items.begin(), items.end(), posLessThan); const QString expression("start();"); QQmlExpression *expr; expr = new QQmlExpression(queryObject->engine->rootContext(), queryObject->qmlElement, expression); expr->evaluate(); - waitForCallback2(); + callbackData.clear(); + waitForCallback1(); QCOMPARE(callbackError, false); - QCOMPARE(cbData.size(), 1); + QCOMPARE(callbackData.size(), 1); QVariantMap item = items[0].toMap(); - QVariantMap obj = cbData[0].toMap(); + QVariantMap obj = callbackData[0].toMap(); QCOMPARE(obj.value("alphabet"), item.value("alphabet")); delete expr; deleteComponent(queryObject); @@ -393,13 +398,14 @@ void TestJsonDbQueryObject::queryError() queryObject->qmlElement->setProperty("bindings", bindingMap); currentQmlElement = queryObject->qmlElement; - mClient->create(QVariant(items), "com.nokia.shared"); + create(items, "com.nokia.shared"); qSort(items.begin(), items.end(), posLessThan); const QString expression("start();"); QQmlExpression *expr; expr = new QQmlExpression(queryObject->engine->rootContext(), queryObject->qmlElement, expression); expr->evaluate(); - waitForCallback2(); + callbackData.clear(); + waitForCallback1(); QCOMPARE(callbackError, true); delete expr; @@ -416,7 +422,8 @@ void TestJsonDbQueryObject::queryLimit() index.insert("_type", "Index"); index.insert("propertyName", "pos"); index.insert("propertyType", "number"); - mClient->create(index, "com.nokia.shared"); + int id = create(index, "com.nokia.shared"); + waitForResponse1(id); const QString queryString = QString("[?_type = \""+QString( __FUNCTION__ )+"\"][/pos]"); queryObject->qmlElement->setProperty("query", queryString); @@ -425,18 +432,19 @@ void TestJsonDbQueryObject::queryLimit() //Create objects QVariantList items = createObjectList(__FUNCTION__, 10).toList(); - mClient->create(QVariant(items), "com.nokia.shared"); + create(items, "com.nokia.shared"); qSort(items.begin(), items.end(), posLessThan); const QString expression("start();"); QQmlExpression *expr; expr = new QQmlExpression(queryObject->engine->rootContext(), queryObject->qmlElement, expression); expr->evaluate(); - waitForCallback2(); + callbackData.clear(); + waitForCallback1(); QCOMPARE(callbackError, false); - QCOMPARE(cbData.size(), 5); + QCOMPARE(callbackData.size(), 5); for (int i = 0; i<5; i++) { QVariantMap item = items[i].toMap(); - QVariantMap obj = cbData[i].toMap(); + QVariantMap obj = callbackData[i].toMap(); QCOMPARE(obj.value("alphabet"), item.value("alphabet")); } @@ -444,6 +452,5 @@ void TestJsonDbQueryObject::queryLimit() deleteComponent(queryObject); } - QTEST_MAIN(TestJsonDbQueryObject) diff --git a/tests/auto/jsondbqueryobject/testjsondbqueryobject.h b/tests/auto/jsondbqueryobject/testjsondbqueryobject.h index c79745a3..4c2645f6 100644 --- a/tests/auto/jsondbqueryobject/testjsondbqueryobject.h +++ b/tests/auto/jsondbqueryobject/testjsondbqueryobject.h @@ -41,27 +41,13 @@ #ifndef TESTJSONDBQUERYOBJECT_H #define TESTJSONDBQUERYOBJECT_H -#include <QCoreApplication> -#include <QList> -#include <QTest> -#include <QFile> -#include <QProcess> -#include <QEventLoop> -#include <QDebug> -#include <QLocalSocket> -#include <QTimer> -#include <QJSValue> - -#include <jsondb-client.h> -#include <jsondb-error.h> - #include <QAbstractItemModel> -#include "clientwrapper.h" -#include "../../shared/qmltestutil.h" +#include "requestwrapper.h" +#include "qmltestutil.h" QT_USE_NAMESPACE_JSONDB -class TestJsonDbQueryObject: public ClientWrapper +class TestJsonDbQueryObject: public RequestWrapper { Q_OBJECT public: @@ -85,7 +71,7 @@ public slots: void errorSlot(const QVariantMap &newError); void finishedSlot(); -protected slots: +public: void timeout(); private: @@ -95,17 +81,12 @@ private: private: QProcess *mProcess; - QStringList mNotificationsReceived; QList<ComponentData*> mComponents; QString mPluginPath; + bool mTimedOut; - bool callbackError; - int callbackErrorCode; - QString callbackErrorMessage; - QVariantList cbData; - QEventLoop mEventLoop2; QObject *currentQmlElement; - + QVariantList callbackData; }; #endif diff --git a/tests/auto/jsondbsortinglistmodel/jsondbsortinglistmodel.pro b/tests/auto/jsondbsortinglistmodel/jsondbsortinglistmodel.pro index 2915514d..ec3fb699 100644 --- a/tests/auto/jsondbsortinglistmodel/jsondbsortinglistmodel.pro +++ b/tests/auto/jsondbsortinglistmodel/jsondbsortinglistmodel.pro @@ -1,9 +1,9 @@ TEMPLATE = app TARGET = tst_jsondbsortinglistmodel DEPENDPATH += . -INCLUDEPATH += . +INCLUDEPATH += . ../../shared/ -QT = core network testlib gui qml jsondbcompat-private +QT = core network testlib gui qml jsondb CONFIG -= app_bundle CONFIG += testcase @@ -12,5 +12,6 @@ include($$PWD/../../shared/shared.pri) DEFINES += JSONDB_DAEMON_BASE=\\\"$$QT.jsondb.bins\\\" DEFINES += SRCDIR=\\\"$$PWD/\\\" -HEADERS += testjsondbsortinglistmodel.h +HEADERS += testjsondbsortinglistmodel.h \ + $$PWD/../../shared/requestwrapper.h SOURCES += testjsondbsortinglistmodel.cpp diff --git a/tests/auto/jsondbsortinglistmodel/testjsondbsortinglistmodel.cpp b/tests/auto/jsondbsortinglistmodel/testjsondbsortinglistmodel.cpp index 1d048f52..5f828833 100644 --- a/tests/auto/jsondbsortinglistmodel/testjsondbsortinglistmodel.cpp +++ b/tests/auto/jsondbsortinglistmodel/testjsondbsortinglistmodel.cpp @@ -43,7 +43,6 @@ #include <QJSEngine> #include <QQmlListReference> #include "testjsondbsortinglistmodel.h" - #include "../../shared/util.h" static const char dbfile[] = "dbFile-jsondb-listmodel"; @@ -55,22 +54,20 @@ ModelData::~ModelData() { if (model) delete model; - if (parttion1) - delete parttion1; - if (parttion2) - delete parttion2; - if (component) delete component; - if (partitionComponent1) - delete partitionComponent1; - if (partitionComponent2) - delete partitionComponent2; - if (engine) delete engine; } +const QString qmlProgram = QLatin1String( + "import QtQuick 2.0\n" + "import QtJsonDb 1.0 as JsonDb \n" + "JsonDb.JsonDbSortingListModel {" + "id: contactsModel;" + "partitions: [JsonDb.Partition {name: \"com.nokia.shared.1\"}, JsonDb.Partition {name: \"com.nokia.shared.2\"}]" + "}"); + QVariant get(QObject* object, int index, QString propertyName) { QVariant retVal; @@ -100,7 +97,6 @@ int indexOf(QObject* object, const QString &uuid) } TestJsonDbSortingListModel::TestJsonDbSortingListModel() - : mWaitingForNotification(false), mWaitingForDataChange(false), mWaitingForRowsRemoved(false) { } @@ -117,7 +113,6 @@ void TestJsonDbSortingListModel::deleteDbFiles() nameFilter << "objectFile.bin" << "objectFile2.bin"; QFileInfoList databaseFiles = currentDir.entryInfoList(nameFilter, QDir::Files); foreach (QFileInfo fileInfo, databaseFiles) { - //qDebug() << "Deleted : " << fileInfo.fileName(); QFile file(fileInfo.fileName()); file.remove(); } @@ -132,7 +127,7 @@ void TestJsonDbSortingListModel::connectListModel(QAbstractListModel *model) connect(model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), this, SLOT(rowsMoved(QModelIndex,int,int,QModelIndex,int))); connect(model, SIGNAL(stateChanged(State)), - this, SLOT(stateChanged())); + this, SLOT(stateChanged(State))); } void TestJsonDbSortingListModel::initTestCase() @@ -143,29 +138,25 @@ void TestJsonDbSortingListModel::initTestCase() QString socketName = QString("testjsondb_%1").arg(getpid()); mProcess = launchJsonDbDaemon(JSONDB_DAEMON_BASE, socketName, QStringList() << "-base-name" << dbfile); - mClient = new JsonDbClient(this); - connect(mClient, SIGNAL(notified(QString,QtAddOn::JsonDb::JsonDbNotification)), - this, SLOT(notified(QString,QtAddOn::JsonDb::JsonDbNotification))); - connect( mClient, SIGNAL(response(int, const QVariant&)), - this, SLOT(response(int, const QVariant&))); - connect( mClient, SIGNAL(error(int, int, const QString&)), - this, SLOT(error(int, int, const QString&))); + connection = new QJsonDbConnection(); + connection->connectToServer(); mPluginPath = findQMLPluginPath("QtJsonDb"); + if (mPluginPath.isEmpty()) + qDebug() << "Couldn't find the plugin path for the plugin QtJsonDb"; // Create the shared Partitions QVariantMap item; item.insert("_type", "Partition"); item.insert("name", "com.nokia.shared.1"); - int id = mClient->create(item); + int id = create(item); waitForResponse1(id); item.clear(); item.insert("_type", "Partition"); item.insert("name", "com.nokia.shared.2"); - id = mClient->create(item); + id = create(item); waitForResponse1(id); - } QAbstractListModel *TestJsonDbSortingListModel::createModel() @@ -173,40 +164,17 @@ QAbstractListModel *TestJsonDbSortingListModel::createModel() ModelData *newModel = new ModelData(); newModel->engine = new QQmlEngine(); QString error; + Q_ASSERT(!mPluginPath.isEmpty()); if (!newModel->engine->importPlugin(mPluginPath, QString("QtJsonDb"), &error)) { qDebug()<<"Unable to load the plugin :"<<error; delete newModel->engine; return 0; } newModel->component = new QQmlComponent(newModel->engine); - newModel->component->setData("import QtQuick 2.0\nimport QtJsonDb 1.0 as JsonDb \n" - "JsonDb.JsonDbSortingListModel {id: contactsModel}", - QUrl()); + newModel->component->setData(qmlProgram.toLocal8Bit(), QUrl()); newModel->model = newModel->component->create(); if (newModel->component->isError()) qDebug() << newModel->component->errors(); - - newModel->partitionComponent1 = new QQmlComponent(newModel->engine); - newModel->partitionComponent1->setData("import QtQuick 2.0\nimport QtJsonDb 1.0 as JsonDb \n" - "JsonDb.Partition {name: \"com.nokia.shared.1\"}", - QUrl()); - newModel->parttion1 = newModel->partitionComponent1->create(); - if (newModel->partitionComponent1->isError()) - qDebug() << newModel->partitionComponent1->errors(); - - - newModel->partitionComponent2 = new QQmlComponent(newModel->engine); - newModel->partitionComponent2->setData("import QtQuick 2.0\nimport QtJsonDb 1.0 as JsonDb \n" - "JsonDb.Partition {name: \"com.nokia.shared.2\"}", - QUrl()); - newModel->parttion2 = newModel->partitionComponent2->create(); - if (newModel->partitionComponent2->isError()) - qDebug() << newModel->partitionComponent2->errors(); - - QQmlListReference partitions(newModel->model, "partitions", newModel->engine); - partitions.append(newModel->parttion1); - partitions.append(newModel->parttion2); - mModels.append(newModel); return (QAbstractListModel*)(newModel->model); } @@ -236,33 +204,39 @@ void TestJsonDbSortingListModel::cleanupTestCase() // Create items in the model. void TestJsonDbSortingListModel::createItem() { + resetWaitFlags(); QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); - int id = mClient->create(item, "com.nokia.shared.1"); - + int id = create(item, "com.nokia.shared.1"); waitForResponse1(id); QAbstractListModel *listModel = createModel(); if (!listModel) return; listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); - QStringList roleNames = (QStringList() << "_type" << "_uuid" << "name"); listModel->setProperty("roleNames", roleNames); connectListModel(listModel); // now start it working QCOMPARE(listModel->rowCount(), 0); - + mWaitingForStateChanged = true; waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); QCOMPARE(listModel->rowCount(), 1); QCOMPARE(listModel->property("state").toInt(), 2); item.clear(); item.insert("_type", __FUNCTION__); item.insert("name", "Baker"); - id = mClient->create(item, "com.nokia.shared.1"); - waitForItemChanged(); + mItemsCreated = 0; + id = create(item, "com.nokia.shared.1"); + waitForResponse1(id); + while (!mItemsCreated) { + mWaitingForRowsInserted = true; + waitForExitOrTimeout(); + } + QCOMPARE(mWaitingForRowsInserted, false); QCOMPARE(listModel->rowCount(), 2); deleteModel(listModel); @@ -271,10 +245,11 @@ void TestJsonDbSortingListModel::createItem() // Create an item and then update it. void TestJsonDbSortingListModel::updateItemClient() { + resetWaitFlags(); QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); - int id = mClient->create(item,"com.nokia.shared.1"); + int id = create(item,"com.nokia.shared.1"); waitForResponse1(id); QAbstractListModel *listModel = createModel(); @@ -286,20 +261,31 @@ void TestJsonDbSortingListModel::updateItemClient() // now start it working QCOMPARE(listModel->rowCount(), 0); - + mWaitingForStateChanged = true; waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); QCOMPARE(listModel->rowCount(), 1); - item.insert("_uuid", mLastUuid); + QString lastUuid,lastVersion; + QVariantMap lastItem; + if (lastResult.count()) { + lastItem = lastResult[0].toMap(); + lastUuid = lastItem.value("_uuid").toString(); + lastVersion = lastItem.value("_version").toString(); + } + item.insert("_uuid", lastUuid); + item.insert("_version", lastVersion); item.insert("name", "Baker"); - - mWaitingForDataChange = true; - - id = mClient->update(item, "com.nokia.shared.1"); - waitForItemChanged(); + id = update(item, "com.nokia.shared.1"); + waitForResponse1(id); + while (!mItemsUpdated) { + mWaitingForChanged = true; + waitForExitOrTimeout(); + } + QCOMPARE(mWaitingForChanged, false); QCOMPARE(listModel->rowCount(), 1); - QCOMPARE(get(listModel, 0, "_uuid").toString(), mLastUuid); + QCOMPARE(get(listModel, 0, "_uuid").toString(), lastUuid); QCOMPARE(get(listModel, 0, "_type").toString(), QLatin1String(__FUNCTION__)); QCOMPARE(get(listModel,0, "name").toString(), QLatin1String("Baker")); deleteModel(listModel); @@ -307,10 +293,11 @@ void TestJsonDbSortingListModel::updateItemClient() void TestJsonDbSortingListModel::deleteItem() { + resetWaitFlags(); QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); - int id = mClient->create(item, "com.nokia.shared.1"); + int id = create(item, "com.nokia.shared.1"); waitForResponse1(id); QAbstractListModel *listModel = createModel(); @@ -321,19 +308,38 @@ void TestJsonDbSortingListModel::deleteItem() connectListModel(listModel); // now start it working + mWaitingForStateChanged = true; waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); QCOMPARE(listModel->rowCount(), 1); item.insert("name", "Baker"); - id = mClient->create(item, "com.nokia.shared.2"); + mItemsCreated = 0; + id = create(item, "com.nokia.shared.2"); waitForResponse1(id); - + while (!mItemsCreated) { + mWaitingForRowsInserted = true; + waitForExitOrTimeout(); + } + QCOMPARE(mWaitingForRowsInserted, false); QCOMPARE(listModel->rowCount(), 2); - mWaitingForRowsRemoved = true; - item.insert("_uuid", mLastUuid); - id = mClient->remove(item, "com.nokia.shared.2"); - waitForItemChanged(true); + QString lastUuid,lastVersion; + QVariantMap lastItem; + if (lastResult.count()) { + lastItem = lastResult[0].toMap(); + lastUuid = lastItem.value("_uuid").toString(); + lastVersion = lastItem.value("_version").toString(); + } + item.insert("_uuid", lastUuid); + item.insert("_version", lastVersion); + id = remove(item, "com.nokia.shared.2"); + waitForResponse1(id); + while (!mItemsRemoved) { + mWaitingForRemoved = true; + waitForExitOrTimeout(); + } + QCOMPARE(mWaitingForRemoved, false); QCOMPARE(listModel->rowCount(), 1); QCOMPARE(get(listModel, 0, "_type").toString(), QLatin1String(__FUNCTION__)); @@ -343,12 +349,13 @@ void TestJsonDbSortingListModel::deleteItem() void TestJsonDbSortingListModel::sortedQuery() { + resetWaitFlags(); int id = 0; for (int i = 0; i < 1000; i++) { QVariantMap item; item.insert("_type", "RandNumber"); item.insert("number", i); - id = mClient->create(item,"com.nokia.shared.2"); + id = create(item,"com.nokia.shared.2"); waitForResponse1(id); } @@ -362,7 +369,9 @@ void TestJsonDbSortingListModel::sortedQuery() listModel->setProperty("roleNames", rolenames); listModel->setProperty("sortOrder", "[/number]"); listModel->setProperty("query", "[?_type=\"RandNumber\"]"); + mWaitingForStateChanged = true; waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); QCOMPARE(listModel->property("sortOrder").toString(), QString("[/number]")); @@ -393,12 +402,13 @@ bool greaterThan(const QString &s1, const QString &s2) void TestJsonDbSortingListModel::ordering() { + resetWaitFlags(); for (int i = 9; i >= 1; --i) { QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); item.insert("order", QString::number(i)); - int id = mClient->create(item, "com.nokia.shared.2"); + int id = create(item, "com.nokia.shared.2"); waitForResponse1(id); } @@ -412,7 +422,9 @@ void TestJsonDbSortingListModel::ordering() // now start it working QCOMPARE(listModel->rowCount(), 0); + mWaitingForStateChanged = true; waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); QStringList expectedOrder = QStringList() << "1" << "2" << "3" << "4" << "5" << "6" << "7" << "8" << "9"; QCOMPARE(getOrderValues(listModel), expectedOrder); @@ -425,13 +437,18 @@ void TestJsonDbSortingListModel::ordering() item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); item.insert("order", "99"); // move it to the end - mClient->update(item, "com.nokia.shared.2"); + update(item, "com.nokia.shared.2"); + } + while (!mItemsUpdated) { + mWaitingForChanged = true; + waitForExitOrTimeout(); } - waitForItemChanged(); + QCOMPARE(mWaitingForChanged, false); expectedOrder = QStringList() << "1" << "2" << "3" << "4" << "6" << "7" << "8" << "9" << "99"; QCOMPARE(getOrderValues(listModel), expectedOrder); + mItemsUpdated = 0; { QVariant uuid = get(listModel, 8, "_uuid"); QVERIFY(!uuid.toString().isEmpty()); @@ -441,13 +458,18 @@ void TestJsonDbSortingListModel::ordering() item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); item.insert("order", "22"); // move it after "2" - mClient->update(item, "com.nokia.shared.2"); + update(item, "com.nokia.shared.2"); } - waitForItemChanged(); + while (!mItemsUpdated) { + mWaitingForChanged = true; + waitForExitOrTimeout(); + } + QCOMPARE(mWaitingForChanged, false); expectedOrder = QStringList() << "1" << "2" << "22" << "3" << "4" << "6" << "7" << "8" << "9"; QCOMPARE(getOrderValues(listModel), expectedOrder); + mItemsUpdated = 0; { QVariant uuid = get(listModel, 5, "_uuid"); QVERIFY(!uuid.toString().isEmpty()); @@ -457,9 +479,13 @@ void TestJsonDbSortingListModel::ordering() item.insert("_type", __FUNCTION__); item.insert("name", "Charlie"); item.insert("order", "0"); // move it to the beginning - mClient->update(item, "com.nokia.shared.2"); + update(item, "com.nokia.shared.2"); + } + while (!mItemsUpdated) { + mWaitingForChanged = true; + waitForExitOrTimeout(); } - waitForItemChanged(); + QCOMPARE(mWaitingForChanged, false); // Check for order and togther with queryLimit expectedOrder = QStringList() << "0" << "1" << "2" << "22" << "3" << @@ -474,23 +500,27 @@ void TestJsonDbSortingListModel::ordering() QCOMPARE(getOrderValues(listModel), expectedOrder); listModel->setProperty("queryLimit", 5); + mWaitingForStateChanged = true; waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); QCOMPARE(listModel->rowCount(), 5); QCOMPARE(getOrderValues(listModel), QStringList(expectedOrder.mid(0, 5))); listModel->setProperty("sortOrder", "[\\order]"); + mWaitingForStateChanged = true; waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); QCOMPARE(listModel->rowCount(), 5); QCOMPARE(getOrderValues(listModel), QStringList(reverseOrder.mid(0, 5))); deleteModel(listModel); - } void TestJsonDbSortingListModel::checkRemoveNotification() { + resetWaitFlags(); QVariantList itemList; for (int i = 0; i < 50; i++) { QVariantMap item; @@ -499,7 +529,7 @@ void TestJsonDbSortingListModel::checkRemoveNotification() item.insert("order", i); itemList << item; } - int id = mClient->create(itemList,"com.nokia.shared.2"); + int id = create(itemList,"com.nokia.shared.2"); waitForResponse1(id); { @@ -511,9 +541,12 @@ void TestJsonDbSortingListModel::checkRemoveNotification() listModel->setProperty("sortOrder", "[/order]"); QStringList roleNames = (QStringList() << "_type" << "_uuid" << "_version"<< "name" << "order"); listModel->setProperty("roleNames", roleNames); - waitForStateOrTimeout(); + mWaitingForStateChanged = true; + waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); QCOMPARE(listModel->rowCount(), 10); + QVariant result = get(listModel, 0, "order"); QVERIFY(result.isValid()); QCOMPARE(result.toInt(), 0); @@ -525,8 +558,10 @@ void TestJsonDbSortingListModel::checkRemoveNotification() QVariantMap item; item.insert("_uuid", get(listModel, 0, "_uuid")); item.insert("_version", get(listModel, 0, "_version")); - id = mClient->remove(item, "com.nokia.shared.2"); - waitForItemChanged(); + id = remove(item, "com.nokia.shared.2"); + waitForResponse1(id); + waitForStateChanged(listModel); + QCOMPARE(listModel->rowCount(), 10); result = get(listModel, 9, "order"); QVERIFY(result.isValid()); @@ -535,8 +570,10 @@ void TestJsonDbSortingListModel::checkRemoveNotification() //Remove item at 9 item.insert("_uuid", get(listModel, 9, "_uuid")); item.insert("_version", get(listModel, 9, "_version")); - id = mClient->remove(item, "com.nokia.shared.2"); - waitForItemChanged(); + id = remove(item, "com.nokia.shared.2"); + waitForResponse1(id); + waitForStateChanged(listModel); + QCOMPARE(listModel->rowCount(), 10); result = get(listModel, 9, "order"); QVERIFY(result.isValid()); @@ -545,8 +582,10 @@ void TestJsonDbSortingListModel::checkRemoveNotification() //Remove item at 4 item.insert("_uuid", get(listModel, 4, "_uuid")); item.insert("_version", get(listModel, 4, "_version")); - id = mClient->remove(item, "com.nokia.shared.2"); - waitForItemChanged(); + id = remove(item, "com.nokia.shared.2"); + waitForResponse1(id); + waitForStateChanged(listModel); + QCOMPARE(listModel->rowCount(), 10); result = get(listModel, 4, "order"); QVERIFY(result.isValid()); @@ -568,7 +607,7 @@ void TestJsonDbSortingListModel::checkUpdateNotification() item.insert("order", i); itemList << item; } - int id = mClient->create(itemList, "com.nokia.shared.1"); + int id = create(itemList, "com.nokia.shared.1"); waitForResponse1(id); { @@ -580,9 +619,12 @@ void TestJsonDbSortingListModel::checkUpdateNotification() listModel->setProperty("sortOrder", "[/order]"); QStringList roleNames = (QStringList() << "_type" << "_uuid" << "_version"<< "name" << "order"); listModel->setProperty("roleNames", roleNames); - waitForStateOrTimeout(); + mWaitingForStateChanged = true; + waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); QCOMPARE(listModel->rowCount(), 10); + QVariant result = get(listModel, 0, "order"); QVERIFY(result.isValid()); QCOMPARE(result.toInt(), 0); @@ -596,8 +638,10 @@ void TestJsonDbSortingListModel::checkUpdateNotification() item.insert("_type", get(listModel, 0, "_type")); item.insert("name", get(listModel, 0, "name")); item.insert("order", 1); - id = mClient->update(item, "com.nokia.shared.1"); + id = update(item, "com.nokia.shared.1"); + waitForItemChanged(); + QCOMPARE(mWaitingForChanged, false); QCOMPARE(listModel->rowCount(), 10); result = get(listModel, 0, "order"); @@ -613,16 +657,11 @@ void TestJsonDbSortingListModel::checkUpdateNotification() item.insert("_type", get(listModel, 9, "_type")); item.insert("name", get(listModel, 9, "name")); item.insert("order", 19); - id = mClient->update(item,"com.nokia.shared.1"); - waitForItemChanged(); + id = update(item,"com.nokia.shared.1"); - item.clear(); - item.insert("_uuid", get(listModel, 9, "_uuid")); - item.insert("_type", get(listModel, 9, "_type")); - item.insert("name", get(listModel, 9, "name")); - item.insert("order", 19); - id = mClient->update(item,"com.nokia.shared.1"); waitForItemChanged(); + QCOMPARE(mWaitingForStateChanged, false); + waitForStateChanged(listModel); QCOMPARE(listModel->rowCount(), 10); result = get(listModel, 0, "order"); @@ -637,8 +676,11 @@ void TestJsonDbSortingListModel::checkUpdateNotification() item.insert("_type", get(listModel, 9, "_type")); item.insert("name", get(listModel, 9, "name")); item.insert("order", 59); - id = mClient->update(item, "com.nokia.shared.1"); + id = update(item, "com.nokia.shared.1"); + waitForItemChanged(); + QCOMPARE(mWaitingForStateChanged, false); + waitForStateChanged(listModel); QCOMPARE(listModel->rowCount(), 10); result = get(listModel, 0, "order"); @@ -653,8 +695,11 @@ void TestJsonDbSortingListModel::checkUpdateNotification() item.insert("_type", get(listModel, 8, "_type")); item.insert("name", get(listModel, 8, "name")); item.insert("order", 17); - id = mClient->update(item, "com.nokia.shared.1"); + id = update(item, "com.nokia.shared.1"); + waitForItemChanged(); + QCOMPARE(mWaitingForStateChanged, false); + waitForStateChanged(listModel); QCOMPARE(listModel->rowCount(), 10); result = get(listModel, 8, "order"); @@ -673,15 +718,16 @@ void TestJsonDbSortingListModel::checkUpdateNotification() void TestJsonDbSortingListModel::totalRowCount() { + resetWaitFlags(); int id = 0; QVariantList insertedItems; for (int i = 0; i < 10; i++) { QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("order", i); - id = mClient->create(item, "com.nokia.shared.1"); + id = create(item, "com.nokia.shared.1"); waitForResponse1(id); - insertedItems << mData; + insertedItems << lastResult; } QAbstractListModel *listModel = createModel(); @@ -689,34 +735,50 @@ void TestJsonDbSortingListModel::totalRowCount() return; connectListModel(listModel); - listModel->setProperty("queryLimit", 50); + listModel->setProperty("queryLimit", 100); listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); QStringList roleNames = (QStringList() << "_type" << "_uuid" << "order"); listModel->setProperty("roleNames", roleNames); + mWaitingForStateChanged = true; waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); QCOMPARE(listModel->rowCount(), 10); + mItemsCreated = 0; for (int i = 10; i < 50; i++) { QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("order", i); - mClient->create(item, "com.nokia.shared.2"); + id = create(item, "com.nokia.shared.2"); + waitForResponse1(id); } - waitForItemsCreated(40); + waitForItemsCreated(40); // will set mWaitingForRowsInserted = true for you + if (id != lastRequestId) + waitForResponse1(id); + QCOMPARE(mWaitingForRowsInserted, false); + QCOMPARE(mItemsCreated, 40); QCOMPARE(listModel->rowCount(), 50); // Change sort order + mWaitingForReadyState = true; listModel->setProperty("sortOrder", "[\\order]"); - waitForStateOrTimeout(); + QVariant state = listModel->property("state"); + if (state.toInt() != 2) { + waitForReadyStateOrTimeout(); + QCOMPARE(mWaitingForReadyState, false); + } + else + mWaitingForReadyState = false; QCOMPARE(listModel->rowCount(), 50); // Delete the first 10 items foreach (QVariant item, insertedItems) { - mWaitingForRowsRemoved = true; - id = mClient->remove(item.toMap(), "com.nokia.shared.1"); - waitForItemChanged(true); + mItemsRemoved = 0; + id = remove(item.toMap(), "com.nokia.shared.1"); + waitForResponse1(id); + waitForItemsRemoved(1); } QCOMPARE(listModel->rowCount(), 40); @@ -726,15 +788,16 @@ void TestJsonDbSortingListModel::totalRowCount() void TestJsonDbSortingListModel::listProperty() { + resetWaitFlags(); QVariant jsonData = readJsonFile(findFile("list-objects.json")).toVariant(); QVariantList itemList = jsonData.toList(); int id = 0; for (int i = 0; i < itemList.count()/2; i++) { - id = mClient->create(itemList[i].toMap(), "com.nokia.shared.1"); + id = create(itemList[i].toMap(), "com.nokia.shared.1"); waitForResponse1(id); } for (int i = itemList.count()/2; i < itemList.count(); i++) { - id = mClient->create(itemList[i].toMap(), "com.nokia.shared.2"); + id = create(itemList[i].toMap(), "com.nokia.shared.2"); waitForResponse1(id); } @@ -748,13 +811,17 @@ void TestJsonDbSortingListModel::listProperty() listModel->setProperty("sortOrder", "[/features.0.properties.0.description]"); QStringList roleNames = (QStringList() << "_type" << "_uuid" << "features.0.properties.0.description"<< "features.0.feature"); listModel->setProperty("roleNames", roleNames); + mWaitingForStateChanged = true; waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); QCOMPARE(listModel->rowCount(), itemList.count()); + QCOMPARE(get(listModel, 0, "_type").toString(), type); QCOMPARE(get(listModel, 0, "features.0.properties.0.description").toString(), QLatin1String("Facebook account provider")); QCOMPARE(get(listModel, 0, "features.0.feature").toString(), QLatin1String("provide Facebook")); - QCOMPARE(get(listModel, 1, "_uuid").toString(), mLastUuid); + //Liang: todo or not? + //QCOMPARE(get(listModel, 1, "_uuid").toString(), mLastUuid); QCOMPARE(get(listModel, 1, "_type").toString(), type); QCOMPARE(get(listModel, 1, "features.0.properties.0.description").toString(), QLatin1String("Gmail account provider")); QCOMPARE(get(listModel, 1, "features.0.feature").toString(), QLatin1String("provide Gmail")); @@ -772,7 +839,9 @@ void TestJsonDbSortingListModel::listProperty() roleNames.clear(); roleNames = (QStringList() << "_type" << "_uuid" << "features[0].properties[0].description"<< "features[0].supported[0]"); listModel->setProperty("roleNames", roleNames); + mWaitingForStateChanged = true; waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); QCOMPARE(listModel->rowCount(), itemList.count()); QCOMPARE(get(listModel, 0, "_type").toString(), type); @@ -785,23 +854,23 @@ void TestJsonDbSortingListModel::listProperty() deleteModel(listModel); } - // Populate model of 300 items two partitions. void TestJsonDbSortingListModel::twoPartitions() { + resetWaitFlags(); QVariantMap item; for (int i=0; i < 300; i = i+2) { item.insert("_type", __FUNCTION__); item.insert("name", QString("Arnie_%1").arg(i)); - int id = mClient->create(item, "com.nokia.shared.1"); + int id = create(item, "com.nokia.shared.1"); waitForResponse1(id); } for (int i=1; i < 300; i = i+2) { item.insert("_type", __FUNCTION__); item.insert("name", QString("Arnie_%1").arg(i)); - int id = mClient->create(item, "com.nokia.shared.2"); + int id = create(item, "com.nokia.shared.2"); waitForResponse1(id); } @@ -814,7 +883,9 @@ void TestJsonDbSortingListModel::twoPartitions() listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); connectListModel(listModel); + mWaitingForStateChanged = true; waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); QCOMPARE(listModel->rowCount(), 300); QCOMPARE(get(listModel, 0, "name").toString(), QString("Arnie_0")); @@ -827,12 +898,13 @@ void TestJsonDbSortingListModel::twoPartitions() void TestJsonDbSortingListModel::changeQuery() { + resetWaitFlags(); QVariantMap item; for (int i=0; i < 10; i++) { item.insert("_type", __FUNCTION__); item.insert("name", QString("Arnie_%1").arg(i)); - int id = mClient->create(item, "com.nokia.shared.1"); + int id = create(item, "com.nokia.shared.1"); waitForResponse1(id); } @@ -845,7 +917,9 @@ void TestJsonDbSortingListModel::changeQuery() listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); connectListModel(listModel); + mWaitingForStateChanged = true; waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); QCOMPARE(listModel->rowCount(), 10); QCOMPARE(listModel->property("query").toString(), QString("[?_type=\"%1\"]").arg(__FUNCTION__)); @@ -861,7 +935,10 @@ void TestJsonDbSortingListModel::changeQuery() QCOMPARE(listModel->property("query").toString(), QString("")); listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); + + mWaitingForStateChanged = true; waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); QCOMPARE(listModel->rowCount(), 10); QCOMPARE(listModel->property("query").toString(), QString("[?_type=\"%1\"]").arg(__FUNCTION__)); @@ -871,12 +948,13 @@ void TestJsonDbSortingListModel::changeQuery() void TestJsonDbSortingListModel::getQJSValue() { + resetWaitFlags(); QVariantMap item; for (int i=0; i < 10; i++) { item.insert("_type", __FUNCTION__); item.insert("name", QString("Arnie_%1").arg(i)); - int id = mClient->create(item, "com.nokia.shared.1"); + int id = create(item, "com.nokia.shared.1"); waitForResponse1(id); } @@ -889,7 +967,9 @@ void TestJsonDbSortingListModel::getQJSValue() listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); connectListModel(listModel); + mWaitingForStateChanged = true; waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); QCOMPARE(listModel->rowCount(), 10); QCOMPARE(get(listModel, 0).property("object").property("name").toString(), QString("Arnie_0")); @@ -898,13 +978,13 @@ void TestJsonDbSortingListModel::getQJSValue() deleteModel(listModel); } - void TestJsonDbSortingListModel::indexOfUuid() { + resetWaitFlags(); QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("name", QString("Arnie_0")); - int id = mClient->create(item, "com.nokia.shared.1"); + int id = create(item, "com.nokia.shared.1"); waitForResponse1(id); QAbstractListModel *listModel = createModel(); @@ -916,7 +996,9 @@ void TestJsonDbSortingListModel::indexOfUuid() listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); connectListModel(listModel); + mWaitingForStateChanged = true; waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); QCOMPARE(listModel->rowCount(), 1); QCOMPARE(get(listModel, 0, "name").toString(), QString("Arnie_0")); @@ -924,9 +1006,14 @@ void TestJsonDbSortingListModel::indexOfUuid() item.insert("_type", __FUNCTION__); item.insert("name", QString("Arnie_1")); - id = mClient->create(item, "com.nokia.shared.1"); + id = create(item, "com.nokia.shared.1"); + waitForResponse1(id); - waitForItemsCreated(1); + waitForItemsCreated(1); // will set mWaitingForRowsInserted = true for you + if (id != lastRequestId) + waitForResponse1(id); + QCOMPARE(mWaitingForRowsInserted, false); + QCOMPARE(mItemsCreated, 1); QCOMPARE(listModel->rowCount(), 2); QCOMPARE(get(listModel, 1, "name").toString(), QString("Arnie_1")); @@ -938,12 +1025,13 @@ void TestJsonDbSortingListModel::indexOfUuid() void TestJsonDbSortingListModel::queryLimit() { + resetWaitFlags(); QVariantMap item; for (int i=0; i < 300; i++) { item.insert("_type", __FUNCTION__); item.insert("name", QString("Arnie_%1").arg(i)); - int id = mClient->create(item, "com.nokia.shared.1"); + int id = create(item, "com.nokia.shared.1"); waitForResponse1(id); } @@ -957,7 +1045,9 @@ void TestJsonDbSortingListModel::queryLimit() listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); connectListModel(listModel); + mWaitingForStateChanged = true; waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); QCOMPARE(listModel->rowCount(), 100); QCOMPARE(listModel->property("overflow").toBool(), true); @@ -968,7 +1058,10 @@ void TestJsonDbSortingListModel::queryLimit() listModel->setProperty("queryLimit", 500); + mWaitingForStateChanged = true; waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); + QCOMPARE(listModel->rowCount(), 300); QCOMPARE(listModel->property("overflow").toBool(), false); @@ -977,15 +1070,15 @@ void TestJsonDbSortingListModel::queryLimit() void TestJsonDbSortingListModel::roleNames() { + resetWaitFlags(); QVariantMap item; item.insert("_type", __FUNCTION__); item.insert("name", QString("Arnie")); item.insert("friend", QString("Bert")); - int id = mClient->create(item, "com.nokia.shared.1"); + int id = create(item, "com.nokia.shared.1"); waitForResponse1(id); - QAbstractListModel *listModel = createModel(); if (!listModel) return; @@ -994,7 +1087,9 @@ void TestJsonDbSortingListModel::roleNames() listModel->setProperty("query", QString("[?_type=\"%1\"]").arg(__FUNCTION__)); connectListModel(listModel); + mWaitingForStateChanged = true; waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); QCOMPARE(listModel->rowCount(), 1); @@ -1016,7 +1111,6 @@ void TestJsonDbSortingListModel::roleNames() deleteModel(listModel); } - QStringList TestJsonDbSortingListModel::getOrderValues(QAbstractListModel *listModel) { QStringList vals; @@ -1027,15 +1121,23 @@ QStringList TestJsonDbSortingListModel::getOrderValues(QAbstractListModel *listM void TestJsonDbSortingListModel::modelReset() { - mWaitingForReset = false; - mEventLoop2.exit(0); + //qDebug() << "modelReset"; + if (mWaitingForReset) { + mWaitingForReset = false; + eventLoop1.exit(0); + } } void TestJsonDbSortingListModel::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { Q_UNUSED(topLeft); Q_UNUSED(bottomRight); - mWaitingForDataChange = false; + mItemsUpdated++; + //qDebug() << "mItemsUpdated++" << mItemsUpdated; + if (mWaitingForChanged) { + mWaitingForChanged = false; + eventLoop1.exit(0); + } } void TestJsonDbSortingListModel::rowsInserted(const QModelIndex &parent, int first, int last) @@ -1044,7 +1146,11 @@ void TestJsonDbSortingListModel::rowsInserted(const QModelIndex &parent, int fir Q_UNUSED(first); Q_UNUSED(last); mItemsCreated++; - mEventLoop2.exit(0); + //qDebug() << "mItemsCreated++" << mItemsCreated; + if (mWaitingForRowsInserted) { + mWaitingForRowsInserted = false; + eventLoop1.exit(0); + } } void TestJsonDbSortingListModel::rowsRemoved(const QModelIndex &parent, int first, int last) @@ -1052,95 +1158,176 @@ void TestJsonDbSortingListModel::rowsRemoved(const QModelIndex &parent, int firs Q_UNUSED(parent); Q_UNUSED(first); Q_UNUSED(last); - mWaitingForRowsRemoved = false; + mItemsRemoved++; + //qDebug() << "mItemsRemoved++" << mItemsRemoved; + if (mWaitingForRemoved) { + mWaitingForRemoved = false; + eventLoop1.exit(0); + } } void TestJsonDbSortingListModel::rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row ) { Q_UNUSED(parent); + Q_UNUSED(start); Q_UNUSED(end); Q_UNUSED(destination); Q_UNUSED(row); } -void TestJsonDbSortingListModel::stateChanged() +void TestJsonDbSortingListModel::stateChanged(State state) { - mWaitingForStateChanged = false; - mEventLoop2.exit(0); + if (mWaitingForStateChanged) { + mWaitingForStateChanged = false; + eventLoop1.exit(0); + } + else if (mWaitingForReadyState && state == Ready) { + mWaitingForReadyState = false; + eventLoop1.exit(0); + } } void TestJsonDbSortingListModel::waitForItemsCreated(int items) { - mTimeoutCalled = false; + mTimedOut = false; QTimer timer; QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); - QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit())); - timer.start(mClientTimeout); - mElapsedTimer.start(); + timer.start(clientTimeout); + elapsedTimer.start(); - mItemsCreated = 0; - while (mItemsCreated != items && !mTimeoutCalled) - mEventLoop2.processEvents(QEventLoop::AllEvents, mClientTimeout); + while (!mTimedOut && mItemsCreated != items) { + mWaitingForRowsInserted = true; + eventLoop1.exec(QEventLoop::AllEvents); + } +} + +void TestJsonDbSortingListModel::waitForItemsRemoved(int items) +{ + mTimedOut = false; + QTimer timer; + QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); + timer.start(clientTimeout); + elapsedTimer.start(); + + while (!mTimedOut && mItemsRemoved != items) { + mWaitingForRemoved = true; + eventLoop1.exec(QEventLoop::AllEvents); + } + if (mTimedOut) + qDebug () << "waitForItemsRemoved Timed out"; } void TestJsonDbSortingListModel::waitForExitOrTimeout() { - mTimeoutCalled = false; QTimer timer; QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); - QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit())); - timer.start(mClientTimeout); - mElapsedTimer.start(); - mEventLoop2.exec(QEventLoop::AllEvents); + timer.start(clientTimeout); + elapsedTimer.start(); + eventLoop1.exec(QEventLoop::AllEvents); +} + +void TestJsonDbSortingListModel::waitForReadyStateOrTimeout() +{ + mTimedOut = false; + QTimer timer; + QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); + timer.start(clientTimeout); + elapsedTimer.start(); + + while (mWaitingForReadyState && !mTimedOut) + eventLoop1.exec(QEventLoop::AllEvents); } void TestJsonDbSortingListModel::waitForStateOrTimeout() { - mTimeoutCalled = false; + mTimedOut = false; QTimer timer; QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); - QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit())); - timer.start(mClientTimeout); - mElapsedTimer.start(); + timer.start(clientTimeout); + elapsedTimer.start(); - mWaitingForStateChanged = true; - while (mWaitingForStateChanged && !mTimeoutCalled) - mEventLoop2.processEvents(QEventLoop::AllEvents, mClientTimeout); + while (mWaitingForStateChanged && !mTimedOut) + eventLoop1.exec(QEventLoop::AllEvents); } void TestJsonDbSortingListModel::timeout() { - ClientWrapper::timeout(); - mTimeoutCalled = true; + RequestWrapper::timeout(); + mTimedOut = true; + eventLoop1.quit(); +} + +void TestJsonDbSortingListModel::resetWaitFlags() +{ + mItemsCreated = 0; + mItemsUpdated = 0; + mItemsRemoved = 0; + mWaitingForRowsInserted = false; + mWaitingForReset = false; + mWaitingForChanged = false; + mWaitingForRemoved = false; + mWaitingForStateChanged = false; +} + +void TestJsonDbSortingListModel::waitForStateChanged(QAbstractListModel *listModel) +{ + int currentState; + currentState = listModel->property("state").toInt(); + //1: JsonDbSortingListModel::Querying + if (currentState != 1) { + mWaitingForStateChanged = true; + waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); + currentState = listModel->property("state").toInt(); + } + if (currentState == 1) { + mWaitingForStateChanged = true; + waitForStateOrTimeout(); + QCOMPARE(mWaitingForStateChanged, false); + currentState = listModel->property("state").toInt(); + } } void TestJsonDbSortingListModel::waitForItemChanged(bool waitForRemove) { - mTimeoutCalled = false; + mTimedOut = false; QTimer timer; QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); - QObject::connect(&timer, SIGNAL(timeout()), &mEventLoop2, SLOT(quit())); - timer.start(mClientTimeout); - mElapsedTimer.start(); + timer.start(clientTimeout); + elapsedTimer.start(); - mWaitingForRowsRemoved = true; - mWaitingForDataChange = true; + mWaitingForRemoved = true; + mWaitingForChanged = true; mItemsCreated = 0; mWaitingForReset = true; + mWaitingForStateChanged = true; bool waitMore = true; - while (waitMore && !mTimeoutCalled) { - if (!mWaitingForDataChange) + while (waitMore && !mTimedOut) { + if (!mWaitingForChanged) { + //qDebug() << "waitForItemChanged: mWaitingForChanged"; + break; + } + if (!mWaitingForStateChanged) { + //qDebug() << "waitForItemChanged: mWaitingForStateChanged"; break; - if (mItemsCreated) + } + if (mItemsCreated){ + //qDebug() << "waitForItemChanged: mItemsCreated"; break; - if (!mWaitingForReset) + } + if (!mWaitingForReset){ + //qDebug() << "waitForItemChanged: mWaitingForReset"; break; - if (waitForRemove && !mWaitingForRowsRemoved) + } + if (waitForRemove && !mWaitingForRemoved){ + //qDebug() << "waitForItemChanged: mWaitingForRemoved"; break; - mEventLoop2.processEvents(QEventLoop::AllEvents); + } + eventLoop1.exec(QEventLoop::AllEvents); } } + QTEST_MAIN(TestJsonDbSortingListModel) diff --git a/tests/auto/jsondbsortinglistmodel/testjsondbsortinglistmodel.h b/tests/auto/jsondbsortinglistmodel/testjsondbsortinglistmodel.h index 4366e783..dcbad13b 100644 --- a/tests/auto/jsondbsortinglistmodel/testjsondbsortinglistmodel.h +++ b/tests/auto/jsondbsortinglistmodel/testjsondbsortinglistmodel.h @@ -41,22 +41,9 @@ #ifndef TestJsonDbListModel_H #define TestJsonDbListModel_H -#include <QCoreApplication> -#include <QList> -#include <QTest> -#include <QFile> -#include <QProcess> -#include <QEventLoop> -#include <QDebug> -#include <QLocalSocket> -#include <QTimer> - -#include <jsondb-client.h> -#include <jsondb-error.h> - #include <QAbstractListModel> -#include "clientwrapper.h" -#include "../../shared/qmltestutil.h" +#include "requestwrapper.h" +#include "qmltestutil.h" QT_BEGIN_NAMESPACE class QQmlEngine; @@ -65,7 +52,8 @@ QT_END_NAMESPACE QT_USE_NAMESPACE_JSONDB -class JsonDbListModel; +//class JsonDbListModel; +enum State { None, Querying, Ready }; class ModelData { public: @@ -73,14 +61,10 @@ public: ~ModelData(); QQmlEngine *engine; QQmlComponent *component; - QQmlComponent *partitionComponent1; - QQmlComponent *partitionComponent2; QObject *model; - QObject *parttion1; - QObject *parttion2; }; -class TestJsonDbSortingListModel: public ClientWrapper +class TestJsonDbSortingListModel: public RequestWrapper { Q_OBJECT public: @@ -96,12 +80,12 @@ public slots: void rowsRemoved(const QModelIndex &parent, int first, int last); void rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row ); void modelReset(); - void stateChanged(); - void timeout(); + void stateChanged(State); private slots: void initTestCase(); void cleanupTestCase(); + void createItem(); void updateItemClient(); void deleteItem(); @@ -117,32 +101,37 @@ private slots: void indexOfUuid(); void queryLimit(); void roleNames(); - +public: + void timeout(); private: void waitForExitOrTimeout(); void waitForItemsCreated(int items); + void waitForItemsRemoved(int items); void waitForStateOrTimeout(); + void waitForReadyStateOrTimeout(); + void waitForStateChanged(QAbstractListModel *listModel); void waitForItemChanged(bool waitForRemove = false); QStringList getOrderValues(QAbstractListModel *listModel); QAbstractListModel *createModel(); void deleteModel(QAbstractListModel *model); + void resetWaitFlags(); private: QProcess *mProcess; - QStringList mNotificationsReceived; QList<ModelData*> mModels; QString mPluginPath; - QEventLoop mEventLoop2; // for all listmodel slots // Response values + bool mTimedOut; int mItemsCreated; - bool mWaitingForNotification; - bool mWaitingForDataChange; - bool mWaitingForRowsRemoved; - bool mTimeoutCalled; + int mItemsUpdated; + int mItemsRemoved; + bool mWaitingForRowsInserted; bool mWaitingForReset; + bool mWaitingForChanged; + bool mWaitingForRemoved; bool mWaitingForStateChanged; - + bool mWaitingForReadyState; }; #endif diff --git a/tests/shared/clientwrapper.h b/tests/shared/clientwrapper.h index 92ad8ee0..1fc5b929 100644 --- a/tests/shared/clientwrapper.h +++ b/tests/shared/clientwrapper.h @@ -101,6 +101,22 @@ QT_USE_NAMESPACE_JSONDB #define waitForResponse3(id, code, notificationId) waitForResponse(mEventLoop, this, id, code, notificationId, 0) #define waitForResponse4(id, code, notificationId, count) waitForResponse(mEventLoop, this, id, code, notificationId, count) +#define waitForCallbackGeneric(eventloop) \ +{ \ + QTimer timer; \ + QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); \ + QObject::connect(&timer, SIGNAL(timeout()), &eventloop, SLOT(quit())); \ + timer.start(mClientTimeout); \ + mElapsedTimer.start(); \ + mTimedOut = false;\ + callbackError = false; \ + eventloop.exec(QEventLoop::AllEvents); \ + QCOMPARE(false, mTimedOut); \ +} + +#define waitForCallback() waitForCallbackGeneric(mEventLoop) +#define waitForCallback2() waitForCallbackGeneric(mEventLoop2) + class JsonDbTestNotification { public: diff --git a/tests/shared/qmltestutil.h b/tests/shared/qmltestutil.h index 9d9d4d0f..0d1b78f0 100644 --- a/tests/shared/qmltestutil.h +++ b/tests/shared/qmltestutil.h @@ -50,23 +50,6 @@ #include <QQmlProperty> #include <QDir> -#define waitForCallbackGeneric(eventloop) \ -{ \ - QTimer timer; \ - QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); \ - QObject::connect(&timer, SIGNAL(timeout()), &eventloop, SLOT(quit())); \ - timer.start(mClientTimeout); \ - mElapsedTimer.start(); \ - mTimedOut = false;\ - callbackError = false; \ - eventloop.exec(QEventLoop::AllEvents); \ - QCOMPARE(false, mTimedOut); \ -} - -#define waitForCallback() waitForCallbackGeneric(mEventLoop) -#define waitForCallback2() waitForCallbackGeneric(mEventLoop2) - - inline QVariant createObject(const QString &functionName) { static QStringList greekAlphabets; diff --git a/tests/shared/requestwrapper.h b/tests/shared/requestwrapper.h new file mode 100644 index 00000000..139ce2b7 --- /dev/null +++ b/tests/shared/requestwrapper.h @@ -0,0 +1,282 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtAddOn.JsonDb module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef RequestWrapper_H +#define RequestWrapper_H + +#include <QCoreApplication> +#include <QList> +#include <QTest> +#include <QFile> +#include <QProcess> +#include <QEventLoop> +#include <QDebug> +#include <QLocalSocket> +#include <QTimer> +#include <QQmlEngine> +#include <QQmlComponent> + +#include "qjsondbconnection.h" +#include "qjsondbwriterequest.h" + +QT_USE_NAMESPACE_JSONDB + +#define waitForResponse(eventloop_, id_) \ +{ \ + int givenid_ = (id_); \ + lastRequestId = -1; \ + lastResult.clear(); \ + lastErrorCode = 0; \ + lastErrorMessage.clear(); \ + eventLoop = &eventloop_; \ + \ + QTimer timer; \ + QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); \ + QObject::connect(&timer, SIGNAL(timeout()), eventLoop, SLOT(quit())); \ + timer.start(clientTimeout); \ + elapsedTimer.start(); \ + eventLoop->exec(QEventLoop::AllEvents); \ + eventLoop = 0; \ + if (givenid_ != -1) QVERIFY2((lastRequestId!=-1), "Failed to receive an answer from the db server"); \ + if (givenid_ != -1) QCOMPARE(lastRequestId, givenid_); \ +} + +#define waitForResponseUntilId(eventloop_, id_) \ +{ \ + int givenid_ = (id_); \ + lastRequestId = -1; \ + lastResult.clear(); \ + lastErrorCode = 0; \ + lastErrorMessage.clear(); \ + eventLoop = &eventloop_; \ + \ + QTimer timer; \ + QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); \ + QObject::connect(&timer, SIGNAL(timeout()), eventLoop, SLOT(quit())); \ + timer.start(clientTimeout); \ + elapsedTimer.start(); \ + while (lastRequestId != givenid_) \ + eventLoop->exec(QEventLoop::AllEvents); \ + eventLoop = 0; \ + if (givenid_ != -1) QVERIFY2((lastRequestId!=-1), "Failed to receive an answer from the db server"); \ + if (givenid_ != -1) QCOMPARE(lastRequestId, givenid_); \ +} + +#define waitForResponse1(id) waitForResponse(eventLoop1, id) +#define waitForResponseUntil(id) waitForResponseUntilId(eventLoop1, id) + +#define waitForCallbackGeneric(eventloop) \ +{ \ + QTimer timer; \ + QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); \ + QObject::connect(&timer, SIGNAL(timeout()), &eventloop, SLOT(quit())); \ + timer.start(clientTimeout); \ + elapsedTimer.start(); \ + mTimedOut = false;\ + callbackError = false; \ + eventloop.exec(QEventLoop::AllEvents); \ + QCOMPARE(false, mTimedOut); \ +} + +//#define waitForCallback() waitForCallbackGeneric(eventLoop) +#define waitForCallback1() waitForCallbackGeneric(eventLoop1) + +class RequestWrapper: public QObject +{ + Q_OBJECT +public: + RequestWrapper() + :clientTimeout(20000) + { + if (qgetenv("JSONDB_CLIENT_TIMEOUT").size()) + clientTimeout = QString::fromLatin1(qgetenv("JSONDB_CLIENT_TIMEOUT")).toLong(); + + connect(this, SIGNAL(response(int,QVariantList)), + this, SLOT(onResponse(int,QVariantList))); + connect(this, SIGNAL(error(int,int,QString)), + this, SLOT(onError(int,int,QString))); + } + + ~RequestWrapper() + { + if (connection) + delete connection; + } + + int create(const QVariantMap &item, const QString &partitionName = QString()) + { + QVariantList list; + list.append(item); + return create(list, partitionName); + } + + int create(const QVariantList &list, const QString &partitionName = QString()) + { + QList<QJsonObject> objects; + for (int i = 0; i<list.count(); i++) { + objects.append(QJsonObject::fromVariantMap(list[i].toMap())); + } + QtJsonDb::QJsonDbWriteRequest *request = new QtJsonDb::QJsonDbCreateRequest(objects); + request->setPartition(partitionName); + connect(request, SIGNAL(finished()), this, SLOT(onWriteFinished())); + connect(request, SIGNAL(finished()), request, SLOT(deleteLater())); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SLOT(onWriteError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + request, SLOT(deleteLater())); + connection->send(request); + return request->property("requestId").toInt(); + } + + int update(const QVariantMap &item, const QString &partitionName = QString()) + { + QVariantList list; + list.append(item); + return update(list, partitionName); + } + + int update(const QVariantList &list, const QString &partitionName = QString()) + { + QList<QJsonObject> objects; + for (int i = 0; i<list.count(); i++) { + objects.append(QJsonObject::fromVariantMap(list[i].toMap())); + } + QtJsonDb::QJsonDbWriteRequest *request = new QtJsonDb::QJsonDbUpdateRequest(objects); + request->setPartition(partitionName); + connect(request, SIGNAL(finished()), this, SLOT(onWriteFinished())); + connect(request, SIGNAL(finished()), request, SLOT(deleteLater())); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SLOT(onWriteError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + request, SLOT(deleteLater())); + connection->send(request); + return request->property("requestId").toInt(); + } + + int remove(const QVariantMap &item, const QString &partitionName = QString()) + { + QVariantList list; + list.append(item); + return remove(list, partitionName); + } + + int remove(const QVariantList &list, const QString &partitionName = QString()) + { + QList<QJsonObject> objects; + for (int i = 0; i<list.count(); i++) { + objects.append(QJsonObject::fromVariantMap(list[i].toMap())); + } + QtJsonDb::QJsonDbWriteRequest *request = new QtJsonDb::QJsonDbRemoveRequest(objects); + request->setPartition(partitionName); + connect(request, SIGNAL(finished()), this, SLOT(onWriteFinished())); + connect(request, SIGNAL(finished()), request, SLOT(deleteLater())); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + this, SLOT(onWriteError(QtJsonDb::QJsonDbRequest::ErrorCode,QString))); + connect(request, SIGNAL(error(QtJsonDb::QJsonDbRequest::ErrorCode,QString)), + request, SLOT(deleteLater())); + connection->send(request); + return request->property("requestId").toInt(); + } + +public Q_SLOTS: + void onWriteFinished() + { + QtJsonDb::QJsonDbWriteRequest *request = qobject_cast<QtJsonDb::QJsonDbWriteRequest*>(sender()); + if (request) { + QList<QJsonObject> objects = request->takeResults(); + QVariantList list; + for (int i = 0; i<objects.count(); i++) { + list.append(objects[i].toVariantMap()); + } + emit response(request->property("requestId").toInt(), list); + } + } + void onWriteError(QtJsonDb::QJsonDbRequest::ErrorCode code, const QString &message) + { + QtJsonDb::QJsonDbWriteRequest *request = qobject_cast<QtJsonDb::QJsonDbWriteRequest*>(sender()); + if (request) { + emit error(request->property("requestId").toInt(), int(code), message); + } + } + void onResponse(int id, const QVariantList& list) + { + //qDebug() << "onResponse" << id; + lastRequestId = id; + lastResult = list; + if (eventLoop) + eventLoop->quit(); + } + void onError(int id, int code, const QString &message) + { + qDebug() << "onError" << id; + lastRequestId = id; + lastErrorCode = code; + lastErrorMessage = message; + if (eventLoop) + eventLoop->quit(); + } + virtual void timeout() + { + qDebug() << "RequestWrapper::timeout() " << elapsedTimer.elapsed(); + } +Q_SIGNALS: + void response(int, const QVariantList&); + void error(int, int, const QString&); +protected: + QPointer<QtJsonDb::QJsonDbConnection> connection; + QPointer<QEventLoop> eventLoop; + int lastRequestId; + QVariantList lastResult; + int lastErrorCode; + QString lastErrorMessage; + QEventLoop eventLoop1; + QElapsedTimer elapsedTimer; + int clientTimeout; + + //Liang is trying + bool callbackError; + int callbackErrorCode; + QString callbackErrorMessage; + QVariant callbackMeta; + QVariant callbackResponse; + bool mCallbackReceived; +}; + +#endif |